A React Native app for the ultimate thinking partner.

feat(android): complete Android platform support and UI improvements

- Fix app.json schema errors (remove invalid Android properties)
- Install react-native-get-random-values for crypto polyfill support
- Add crypto polyfill import in polyfills.js
- Update Expo SDK packages to correct versions (expo@54.0.13, expo-font@~14.0.9, react-native-reanimated@~4.1.1)
- Add expo-system-ui for Android system UI color management
- Configure Android keyboard behavior (pan mode, dynamic padding)
- Add dynamic keyboard height tracking to keep input visible above keyboard
- Fix white navigation bar issue with proper background colors
- Update navigation labels from "Knowledge" to "Memory"
- Adjust input container bottom padding for better spacing
- Update app icon

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

Co-Authored-By: Claude <noreply@anthropic.com>

+407 -480
+3 -3
app.json
··· 20 20 "foregroundImage": "./assets/adaptive-icon.png", 21 21 "backgroundColor": "#ffffff" 22 22 }, 23 - "edgeToEdgeEnabled": true, 24 - "statusBarColor": "#1B1B23", 25 - "statusBarStyle": "light" 23 + "package": "com.letta.co", 24 + "backgroundColor": "#1B1B23", 25 + "softwareKeyboardLayoutMode": "pan" 26 26 }, 27 27 "web": { 28 28 "favicon": "./assets/favicon.png",
assets/icon.png

This is a binary file and will not be displayed.

+306 -302
package-lock.json
··· 18 18 "@react-navigation/stack": "^7.4.8", 19 19 "@ronradtke/react-native-markdown-display": "^8.1.0", 20 20 "axios": "^1.11.0", 21 - "expo": "^54.0.0", 21 + "expo": "54.0.13", 22 22 "expo-clipboard": "~8.0.7", 23 - "expo-font": "~14.0.8", 23 + "expo-font": "~14.0.9", 24 24 "expo-image-picker": "~17.0.8", 25 25 "expo-secure-store": "~15.0.7", 26 26 "expo-status-bar": "~3.0.8", 27 + "expo-system-ui": "~6.0.7", 27 28 "lottie-react-native": "~7.3.1", 28 29 "react": "19.1.0", 29 30 "react-dom": "19.1.0", 30 31 "react-native": "0.81.4", 31 32 "react-native-gesture-handler": "~2.28.0", 33 + "react-native-get-random-values": "^1.11.0", 32 34 "react-native-polyfill-globals": "^3.1.0", 33 - "react-native-reanimated": "~4.1.0", 35 + "react-native-reanimated": "~4.1.1", 34 36 "react-native-safe-area-context": "~5.6.0", 35 37 "react-native-screens": "~4.16.0", 36 38 "react-native-svg": "15.12.1", ··· 1570 1572 "integrity": "sha512-uddqvCw9zFeYVUqUmPkCxFqEd+YbmCKqpNpdzj+LhJwYM2AwjR8i+Zq5Qx7KhbP/vzIZUfSwC5bnZ3cx2ltqGw==", 1571 1573 "license": "MIT AND OFL-1.1" 1572 1574 }, 1573 - "node_modules/@expo/cli": { 1574 - "version": "54.0.8", 1575 - "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.8.tgz", 1576 - "integrity": "sha512-bRJXvtjgxpyElmJuKLotWyIW5j9a2K3rGUjd2A8LRcFimrZp0wwuKPQjlUK0sFNbU7zHWfxubNq/B+UkUNkCxw==", 1577 - "license": "MIT", 1578 - "dependencies": { 1579 - "@0no-co/graphql.web": "^1.0.8", 1580 - "@expo/code-signing-certificates": "^0.0.5", 1581 - "@expo/config": "~12.0.9", 1582 - "@expo/config-plugins": "~54.0.1", 1583 - "@expo/devcert": "^1.1.2", 1584 - "@expo/env": "~2.0.7", 1585 - "@expo/image-utils": "^0.8.7", 1586 - "@expo/json-file": "^10.0.7", 1587 - "@expo/mcp-tunnel": "~0.0.7", 1588 - "@expo/metro": "~54.0.0", 1589 - "@expo/metro-config": "~54.0.5", 1590 - "@expo/osascript": "^2.3.7", 1591 - "@expo/package-manager": "^1.9.8", 1592 - "@expo/plist": "^0.4.7", 1593 - "@expo/prebuild-config": "^54.0.3", 1594 - "@expo/schema-utils": "^0.1.7", 1595 - "@expo/server": "^0.7.5", 1596 - "@expo/spawn-async": "^1.7.2", 1597 - "@expo/ws-tunnel": "^1.0.1", 1598 - "@expo/xcpretty": "^4.3.0", 1599 - "@react-native/dev-middleware": "0.81.4", 1600 - "@urql/core": "^5.0.6", 1601 - "@urql/exchange-retry": "^1.3.0", 1602 - "accepts": "^1.3.8", 1603 - "arg": "^5.0.2", 1604 - "better-opn": "~3.0.2", 1605 - "bplist-creator": "0.1.0", 1606 - "bplist-parser": "^0.3.1", 1607 - "chalk": "^4.0.0", 1608 - "ci-info": "^3.3.0", 1609 - "compression": "^1.7.4", 1610 - "connect": "^3.7.0", 1611 - "debug": "^4.3.4", 1612 - "env-editor": "^0.4.1", 1613 - "freeport-async": "^2.0.0", 1614 - "getenv": "^2.0.0", 1615 - "glob": "^10.4.2", 1616 - "lan-network": "^0.1.6", 1617 - "minimatch": "^9.0.0", 1618 - "node-forge": "^1.3.1", 1619 - "npm-package-arg": "^11.0.0", 1620 - "ora": "^3.4.0", 1621 - "picomatch": "^3.0.1", 1622 - "pretty-bytes": "^5.6.0", 1623 - "pretty-format": "^29.7.0", 1624 - "progress": "^2.0.3", 1625 - "prompts": "^2.3.2", 1626 - "qrcode-terminal": "0.11.0", 1627 - "require-from-string": "^2.0.2", 1628 - "requireg": "^0.2.2", 1629 - "resolve": "^1.22.2", 1630 - "resolve-from": "^5.0.0", 1631 - "resolve.exports": "^2.0.3", 1632 - "semver": "^7.6.0", 1633 - "send": "^0.19.0", 1634 - "slugify": "^1.3.4", 1635 - "source-map-support": "~0.5.21", 1636 - "stacktrace-parser": "^0.1.10", 1637 - "structured-headers": "^0.4.1", 1638 - "tar": "^7.4.3", 1639 - "terminal-link": "^2.1.1", 1640 - "undici": "^6.18.2", 1641 - "wrap-ansi": "^7.0.0", 1642 - "ws": "^8.12.1" 1643 - }, 1644 - "bin": { 1645 - "expo-internal": "build/bin/cli" 1646 - }, 1647 - "peerDependencies": { 1648 - "expo": "*", 1649 - "expo-router": "*", 1650 - "react-native": "*" 1651 - }, 1652 - "peerDependenciesMeta": { 1653 - "expo-router": { 1654 - "optional": true 1655 - }, 1656 - "react-native": { 1657 - "optional": true 1658 - } 1659 - } 1660 - }, 1661 - "node_modules/@expo/cli/node_modules/semver": { 1662 - "version": "7.7.2", 1663 - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", 1664 - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", 1665 - "license": "ISC", 1666 - "bin": { 1667 - "semver": "bin/semver.js" 1668 - }, 1669 - "engines": { 1670 - "node": ">=10" 1671 - } 1672 - }, 1673 1575 "node_modules/@expo/code-signing-certificates": { 1674 1576 "version": "0.0.5", 1675 1577 "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.5.tgz", ··· 1681 1583 } 1682 1584 }, 1683 1585 "node_modules/@expo/config": { 1684 - "version": "12.0.9", 1685 - "resolved": "https://registry.npmjs.org/@expo/config/-/config-12.0.9.tgz", 1686 - "integrity": "sha512-HiDVVaXYKY57+L1MxSF3TaYjX6zZlGBnuWnOKZG+7mtsLD+aNTtW4bZM0pZqZfoRumyOU0SfTCwT10BWtUUiJQ==", 1586 + "version": "12.0.10", 1587 + "resolved": "https://registry.npmjs.org/@expo/config/-/config-12.0.10.tgz", 1588 + "integrity": "sha512-lJMof5Nqakq1DxGYlghYB/ogSBjmv4Fxn1ovyDmcjlRsQdFCXgu06gEUogkhPtc9wBt9WlTTfqENln5HHyLW6w==", 1687 1589 "license": "MIT", 1688 1590 "dependencies": { 1689 1591 "@babel/code-frame": "~7.10.4", 1690 - "@expo/config-plugins": "~54.0.1", 1592 + "@expo/config-plugins": "~54.0.2", 1691 1593 "@expo/config-types": "^54.0.8", 1692 1594 "@expo/json-file": "^10.0.7", 1693 1595 "deepmerge": "^4.3.1", ··· 1702 1604 } 1703 1605 }, 1704 1606 "node_modules/@expo/config-plugins": { 1705 - "version": "54.0.1", 1706 - "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-54.0.1.tgz", 1707 - "integrity": "sha512-NyBChhiWFL6VqSgU+LzK4R1vC397tEG2XFewVt4oMr4Pnalq/mJxBANQrR+dyV1RHhSyhy06RNiJIkQyngVWeg==", 1607 + "version": "54.0.2", 1608 + "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-54.0.2.tgz", 1609 + "integrity": "sha512-jD4qxFcURQUVsUFGMcbo63a/AnviK8WUGard+yrdQE3ZrB/aurn68SlApjirQQLEizhjI5Ar2ufqflOBlNpyPg==", 1708 1610 "license": "MIT", 1709 1611 "dependencies": { 1710 1612 "@expo/config-types": "^54.0.8", ··· 1724 1626 } 1725 1627 }, 1726 1628 "node_modules/@expo/config-plugins/node_modules/semver": { 1727 - "version": "7.7.2", 1728 - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", 1729 - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", 1629 + "version": "7.7.3", 1630 + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", 1631 + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", 1730 1632 "license": "ISC", 1731 1633 "bin": { 1732 1634 "semver": "bin/semver.js" ··· 1918 1820 } 1919 1821 } 1920 1822 }, 1823 + "node_modules/@expo/mcp-tunnel/node_modules/ws": { 1824 + "version": "8.18.3", 1825 + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", 1826 + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", 1827 + "license": "MIT", 1828 + "engines": { 1829 + "node": ">=10.0.0" 1830 + }, 1831 + "peerDependencies": { 1832 + "bufferutil": "^4.0.1", 1833 + "utf-8-validate": ">=5.0.2" 1834 + }, 1835 + "peerDependenciesMeta": { 1836 + "bufferutil": { 1837 + "optional": true 1838 + }, 1839 + "utf-8-validate": { 1840 + "optional": true 1841 + } 1842 + } 1843 + }, 1921 1844 "node_modules/@expo/metro": { 1922 1845 "version": "54.0.0", 1923 1846 "resolved": "https://registry.npmjs.org/@expo/metro/-/metro-54.0.0.tgz", ··· 1939 1862 } 1940 1863 }, 1941 1864 "node_modules/@expo/metro-config": { 1942 - "version": "54.0.5", 1943 - "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-54.0.5.tgz", 1944 - "integrity": "sha512-Y+oYtLg8b3L4dHFImfu8+yqO+KOcBpLLjxN7wGbs7miP/BjntBQ6tKbPxyKxHz5UUa1s+buBzZlZhsFo9uqKMg==", 1865 + "version": "54.0.6", 1866 + "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-54.0.6.tgz", 1867 + "integrity": "sha512-z3wufTr1skM03PI6Dr1ZsrvjAiGKf/w0VQvdZL+mEnKNqRA7Q4bhJDGk1+nzs+WWRWz4vS488uad9ERmSclBmg==", 1945 1868 "license": "MIT", 1946 1869 "dependencies": { 1947 1870 "@babel/code-frame": "^7.20.0", 1948 1871 "@babel/core": "^7.20.0", 1949 1872 "@babel/generator": "^7.20.5", 1950 - "@expo/config": "~12.0.9", 1873 + "@expo/config": "~12.0.10", 1951 1874 "@expo/env": "~2.0.7", 1952 1875 "@expo/json-file": "~10.0.7", 1953 1876 "@expo/metro": "~54.0.0", ··· 2285 2208 "node": ">=20.19.4" 2286 2209 } 2287 2210 }, 2288 - "node_modules/@expo/metro/node_modules/ws": { 2289 - "version": "7.5.10", 2290 - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", 2291 - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", 2292 - "license": "MIT", 2293 - "engines": { 2294 - "node": ">=8.3.0" 2295 - }, 2296 - "peerDependencies": { 2297 - "bufferutil": "^4.0.1", 2298 - "utf-8-validate": "^5.0.2" 2299 - }, 2300 - "peerDependenciesMeta": { 2301 - "bufferutil": { 2302 - "optional": true 2303 - }, 2304 - "utf-8-validate": { 2305 - "optional": true 2306 - } 2307 - } 2308 - }, 2309 2211 "node_modules/@expo/osascript": { 2310 2212 "version": "2.3.7", 2311 2213 "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.3.7.tgz", ··· 2345 2247 } 2346 2248 }, 2347 2249 "node_modules/@expo/prebuild-config": { 2348 - "version": "54.0.3", 2349 - "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-54.0.3.tgz", 2350 - "integrity": "sha512-okf6Umaz1VniKmm+pA37QHBzB9XlRHvO1Qh3VbUezy07LTkz87kXUW7uLMmrA319WLavWSVORTXeR0jBRihObA==", 2250 + "version": "54.0.5", 2251 + "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-54.0.5.tgz", 2252 + "integrity": "sha512-eCvbVUf01j1nSrs4mG/rWwY+SfgE30LM6JcElLrnNgNnaDWzt09E/c8n3ZeTLNKENwJaQQ1KIn2VE461/4VnWQ==", 2351 2253 "license": "MIT", 2352 2254 "dependencies": { 2353 - "@expo/config": "~12.0.9", 2354 - "@expo/config-plugins": "~54.0.1", 2255 + "@expo/config": "~12.0.10", 2256 + "@expo/config-plugins": "~54.0.2", 2355 2257 "@expo/config-types": "^54.0.8", 2356 2258 "@expo/image-utils": "^0.8.7", 2357 2259 "@expo/json-file": "^10.0.7", ··· 2366 2268 } 2367 2269 }, 2368 2270 "node_modules/@expo/prebuild-config/node_modules/semver": { 2369 - "version": "7.7.2", 2370 - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", 2371 - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", 2271 + "version": "7.7.3", 2272 + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", 2273 + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", 2372 2274 "license": "ISC", 2373 2275 "bin": { 2374 2276 "semver": "bin/semver.js" ··· 2388 2290 "resolved": "https://registry.npmjs.org/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz", 2389 2291 "integrity": "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==", 2390 2292 "license": "MIT" 2391 - }, 2392 - "node_modules/@expo/server": { 2393 - "version": "0.7.5", 2394 - "resolved": "https://registry.npmjs.org/@expo/server/-/server-0.7.5.tgz", 2395 - "integrity": "sha512-aNVcerBSJEcUspvXRWChEgFhix1gTNIcgFDevaU/A1+TkfbejNIjGX4rfLEpfyRzzdLIRuOkBNjD+uTYMzohyg==", 2396 - "license": "MIT", 2397 - "dependencies": { 2398 - "abort-controller": "^3.0.0", 2399 - "debug": "^4.3.4" 2400 - }, 2401 - "engines": { 2402 - "node": ">=20.16.0" 2403 - } 2404 2293 }, 2405 2294 "node_modules/@expo/spawn-async": { 2406 2295 "version": "1.7.2", ··· 4368 4257 } 4369 4258 }, 4370 4259 "node_modules/bplist-parser": { 4371 - "version": "0.3.2", 4372 - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz", 4373 - "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==", 4260 + "version": "0.3.1", 4261 + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz", 4262 + "integrity": "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==", 4374 4263 "license": "MIT", 4375 4264 "dependencies": { 4376 4265 "big-integer": "1.6.x" ··· 5187 5076 } 5188 5077 }, 5189 5078 "node_modules/detect-libc": { 5190 - "version": "2.1.0", 5191 - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.0.tgz", 5192 - "integrity": "sha512-vEtk+OcP7VBRtQZ1EJ3bdgzSfBjgnEalLTp5zjJrS+2Z1w2KZly4SBdac/WDU3hhsNAZ9E8SC96ME4Ey8MZ7cg==", 5079 + "version": "2.1.2", 5080 + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", 5081 + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", 5193 5082 "license": "Apache-2.0", 5194 5083 "engines": { 5195 5084 "node": ">=8" ··· 5505 5394 "license": "MIT" 5506 5395 }, 5507 5396 "node_modules/expo": { 5508 - "version": "54.0.10", 5509 - "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.10.tgz", 5510 - "integrity": "sha512-49+IginEoKC+g125ZlRvUYNl9jKjjHcDiDnQvejNWlMQ0LtcFIWiFad/PLjmi7YqF/0rj9u3FNxqM6jNP16O0w==", 5397 + "version": "54.0.13", 5398 + "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.13.tgz", 5399 + "integrity": "sha512-F1puKXzw8ESnsbvaKdXtcIiyYLQ2kUHqP8LuhgtJS1wm6w55VhtOPg8yl/0i8kPbTA0YfD+KYdXjSfhPXgUPxw==", 5511 5400 "license": "MIT", 5512 5401 "dependencies": { 5513 5402 "@babel/runtime": "^7.20.0", 5514 - "@expo/cli": "54.0.8", 5515 - "@expo/config": "~12.0.9", 5516 - "@expo/config-plugins": "~54.0.1", 5403 + "@expo/cli": "54.0.11", 5404 + "@expo/config": "~12.0.10", 5405 + "@expo/config-plugins": "~54.0.2", 5517 5406 "@expo/devtools": "0.1.7", 5518 5407 "@expo/fingerprint": "0.15.1", 5519 5408 "@expo/metro": "~54.0.0", 5520 - "@expo/metro-config": "54.0.5", 5409 + "@expo/metro-config": "54.0.6", 5521 5410 "@expo/vector-icons": "^15.0.2", 5522 5411 "@ungap/structured-clone": "^1.3.0", 5523 5412 "babel-preset-expo": "~54.0.3", 5524 5413 "expo-asset": "~12.0.9", 5525 5414 "expo-constants": "~18.0.9", 5526 - "expo-file-system": "~19.0.15", 5527 - "expo-font": "~14.0.8", 5415 + "expo-file-system": "~19.0.17", 5416 + "expo-font": "~14.0.9", 5528 5417 "expo-keep-awake": "~15.0.7", 5529 - "expo-modules-autolinking": "3.0.13", 5530 - "expo-modules-core": "3.0.18", 5418 + "expo-modules-autolinking": "3.0.15", 5419 + "expo-modules-core": "3.0.21", 5531 5420 "pretty-format": "^29.7.0", 5532 5421 "react-refresh": "^0.14.2", 5533 5422 "whatwg-url-without-unicode": "8.0.0-3" ··· 5597 5486 } 5598 5487 }, 5599 5488 "node_modules/expo-file-system": { 5600 - "version": "19.0.15", 5601 - "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-19.0.15.tgz", 5602 - "integrity": "sha512-sRLW+3PVJDiuoCE2LuteHhC7OxPjh1cfqLylf1YG1TDEbbQXnzwjfsKeRm6dslEPZLkMWfSLYIrVbnuq5mF7kQ==", 5489 + "version": "19.0.17", 5490 + "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-19.0.17.tgz", 5491 + "integrity": "sha512-WwaS01SUFrxBnExn87pg0sCTJjZpf2KAOzfImG0o8yhkU7fbYpihpl/oocXBEsNbj58a8hVt1Y4CVV5c1tzu/g==", 5603 5492 "license": "MIT", 5604 5493 "peerDependencies": { 5605 5494 "expo": "*", ··· 5607 5496 } 5608 5497 }, 5609 5498 "node_modules/expo-font": { 5610 - "version": "14.0.8", 5611 - "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.8.tgz", 5612 - "integrity": "sha512-bTUHaJWRZ7ywP8dg3f+wfOwv6RwMV3mWT2CDUIhsK70GjNGlCtiWOCoHsA5Od/esPaVxqc37cCBvQGQRFStRlA==", 5499 + "version": "14.0.9", 5500 + "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.9.tgz", 5501 + "integrity": "sha512-xCoQbR/36qqB6tew/LQ6GWICpaBmHLhg/Loix5Rku/0ZtNaXMJv08M9o1AcrdiGTn/Xf/BnLu6DgS45cWQEHZg==", 5613 5502 "license": "MIT", 5614 5503 "dependencies": { 5615 5504 "fontfaceobserver": "^2.1.0" ··· 5652 5541 } 5653 5542 }, 5654 5543 "node_modules/expo-modules-autolinking": { 5655 - "version": "3.0.13", 5656 - "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.13.tgz", 5657 - "integrity": "sha512-58WnM15ESTyT2v93Rba7jplXtGvh5cFbxqUCi2uTSpBf3nndDRItLzBQaoWBzAvNUhpC2j1bye7Dn/E+GJFXmw==", 5544 + "version": "3.0.15", 5545 + "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.15.tgz", 5546 + "integrity": "sha512-B6c+x664ImrWd+PknEy5454gtY6P0cMxj4P50fvLYP4HimbYj9SzwoHqZ/Rxh9NwxnUkT2nappk/USYIcPoS/A==", 5658 5547 "license": "MIT", 5659 5548 "dependencies": { 5660 5549 "@expo/spawn-async": "^1.7.2", ··· 5669 5558 } 5670 5559 }, 5671 5560 "node_modules/expo-modules-core": { 5672 - "version": "3.0.18", 5673 - "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-3.0.18.tgz", 5674 - "integrity": "sha512-9JPnjlXEFaq/uACZ7I4wb/RkgPYCEsfG75UKMvfl7P7rkymtpRGYj8/gTL2KId8Xt1fpmIPOF57U8tKamjtjXg==", 5561 + "version": "3.0.21", 5562 + "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-3.0.21.tgz", 5563 + "integrity": "sha512-KJRzm0FEt/lfPNG+C6UUq+ta9PO10QPwY1HGCNkzPiRCIMJmQP4xRYK4Z7AxiYEYsPqr5OdjRW55kGZ4c5pzgA==", 5675 5564 "license": "MIT", 5676 5565 "dependencies": { 5677 5566 "invariant": "^2.2.4" ··· 5690 5579 "expo": "*" 5691 5580 } 5692 5581 }, 5582 + "node_modules/expo-server": { 5583 + "version": "1.0.1", 5584 + "resolved": "https://registry.npmjs.org/expo-server/-/expo-server-1.0.1.tgz", 5585 + "integrity": "sha512-J3JlpzNXOkkr4BbapTrcv6klBQcw6NzrBBVIU7qkNE2eU3U1on9rp27wi0+cihjG/QgxSIqQVkrga5z3HWnH0A==", 5586 + "license": "MIT", 5587 + "engines": { 5588 + "node": ">=20.16.0" 5589 + } 5590 + }, 5693 5591 "node_modules/expo-status-bar": { 5694 5592 "version": "3.0.8", 5695 5593 "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-3.0.8.tgz", ··· 5703 5601 "react-native": "*" 5704 5602 } 5705 5603 }, 5604 + "node_modules/expo-system-ui": { 5605 + "version": "6.0.7", 5606 + "resolved": "https://registry.npmjs.org/expo-system-ui/-/expo-system-ui-6.0.7.tgz", 5607 + "integrity": "sha512-NT+/r/BOg08lFI9SZO2WFi9X1ZmawkVStknioWzQq6Mt4KinoMS6yl3eLbyOLM3LoptN13Ywfo4W5KHA6TV9Ow==", 5608 + "license": "MIT", 5609 + "dependencies": { 5610 + "@react-native/normalize-colors": "0.81.4", 5611 + "debug": "^4.3.2" 5612 + }, 5613 + "peerDependencies": { 5614 + "expo": "*", 5615 + "react-native": "*", 5616 + "react-native-web": "*" 5617 + }, 5618 + "peerDependenciesMeta": { 5619 + "react-native-web": { 5620 + "optional": true 5621 + } 5622 + } 5623 + }, 5624 + "node_modules/expo/node_modules/@expo/cli": { 5625 + "version": "54.0.11", 5626 + "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.11.tgz", 5627 + "integrity": "sha512-ik9p8+JTOuVXS462+vFPV0qnWRBXIR1bPmoVKO8xQWw6Yk+K6UlU2GrM2ch7kA3JlSJE/MGsNyN8CB0zFZbVbQ==", 5628 + "license": "MIT", 5629 + "dependencies": { 5630 + "@0no-co/graphql.web": "^1.0.8", 5631 + "@expo/code-signing-certificates": "^0.0.5", 5632 + "@expo/config": "~12.0.10", 5633 + "@expo/config-plugins": "~54.0.2", 5634 + "@expo/devcert": "^1.1.2", 5635 + "@expo/env": "~2.0.7", 5636 + "@expo/image-utils": "^0.8.7", 5637 + "@expo/json-file": "^10.0.7", 5638 + "@expo/mcp-tunnel": "~0.0.7", 5639 + "@expo/metro": "~54.0.0", 5640 + "@expo/metro-config": "~54.0.6", 5641 + "@expo/osascript": "^2.3.7", 5642 + "@expo/package-manager": "^1.9.8", 5643 + "@expo/plist": "^0.4.7", 5644 + "@expo/prebuild-config": "^54.0.5", 5645 + "@expo/schema-utils": "^0.1.7", 5646 + "@expo/spawn-async": "^1.7.2", 5647 + "@expo/ws-tunnel": "^1.0.1", 5648 + "@expo/xcpretty": "^4.3.0", 5649 + "@react-native/dev-middleware": "0.81.4", 5650 + "@urql/core": "^5.0.6", 5651 + "@urql/exchange-retry": "^1.3.0", 5652 + "accepts": "^1.3.8", 5653 + "arg": "^5.0.2", 5654 + "better-opn": "~3.0.2", 5655 + "bplist-creator": "0.1.0", 5656 + "bplist-parser": "^0.3.1", 5657 + "chalk": "^4.0.0", 5658 + "ci-info": "^3.3.0", 5659 + "compression": "^1.7.4", 5660 + "connect": "^3.7.0", 5661 + "debug": "^4.3.4", 5662 + "env-editor": "^0.4.1", 5663 + "expo-server": "^1.0.1", 5664 + "freeport-async": "^2.0.0", 5665 + "getenv": "^2.0.0", 5666 + "glob": "^10.4.2", 5667 + "lan-network": "^0.1.6", 5668 + "minimatch": "^9.0.0", 5669 + "node-forge": "^1.3.1", 5670 + "npm-package-arg": "^11.0.0", 5671 + "ora": "^3.4.0", 5672 + "picomatch": "^3.0.1", 5673 + "pretty-bytes": "^5.6.0", 5674 + "pretty-format": "^29.7.0", 5675 + "progress": "^2.0.3", 5676 + "prompts": "^2.3.2", 5677 + "qrcode-terminal": "0.11.0", 5678 + "require-from-string": "^2.0.2", 5679 + "requireg": "^0.2.2", 5680 + "resolve": "^1.22.2", 5681 + "resolve-from": "^5.0.0", 5682 + "resolve.exports": "^2.0.3", 5683 + "semver": "^7.6.0", 5684 + "send": "^0.19.0", 5685 + "slugify": "^1.3.4", 5686 + "source-map-support": "~0.5.21", 5687 + "stacktrace-parser": "^0.1.10", 5688 + "structured-headers": "^0.4.1", 5689 + "tar": "^7.4.3", 5690 + "terminal-link": "^2.1.1", 5691 + "undici": "^6.18.2", 5692 + "wrap-ansi": "^7.0.0", 5693 + "ws": "^8.12.1" 5694 + }, 5695 + "bin": { 5696 + "expo-internal": "build/bin/cli" 5697 + }, 5698 + "peerDependencies": { 5699 + "expo": "*", 5700 + "expo-router": "*", 5701 + "react-native": "*" 5702 + }, 5703 + "peerDependenciesMeta": { 5704 + "expo-router": { 5705 + "optional": true 5706 + }, 5707 + "react-native": { 5708 + "optional": true 5709 + } 5710 + } 5711 + }, 5712 + "node_modules/expo/node_modules/semver": { 5713 + "version": "7.7.3", 5714 + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", 5715 + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", 5716 + "license": "ISC", 5717 + "bin": { 5718 + "semver": "bin/semver.js" 5719 + }, 5720 + "engines": { 5721 + "node": ">=10" 5722 + } 5723 + }, 5724 + "node_modules/expo/node_modules/ws": { 5725 + "version": "8.18.3", 5726 + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", 5727 + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", 5728 + "license": "MIT", 5729 + "engines": { 5730 + "node": ">=10.0.0" 5731 + }, 5732 + "peerDependencies": { 5733 + "bufferutil": "^4.0.1", 5734 + "utf-8-validate": ">=5.0.2" 5735 + }, 5736 + "peerDependenciesMeta": { 5737 + "bufferutil": { 5738 + "optional": true 5739 + }, 5740 + "utf-8-validate": { 5741 + "optional": true 5742 + } 5743 + } 5744 + }, 5706 5745 "node_modules/exponential-backoff": { 5707 5746 "version": "3.1.2", 5708 5747 "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", ··· 5713 5752 "version": "1.0.0", 5714 5753 "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz", 5715 5754 "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==", 5716 - "license": "MIT", 5717 - "peer": true 5755 + "license": "MIT" 5718 5756 }, 5719 5757 "node_modules/fast-deep-equal": { 5720 5758 "version": "3.1.3", ··· 6787 6825 "license": "MIT" 6788 6826 }, 6789 6827 "node_modules/lightningcss": { 6790 - "version": "1.30.1", 6791 - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", 6792 - "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", 6828 + "version": "1.30.2", 6829 + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", 6830 + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", 6793 6831 "license": "MPL-2.0", 6794 6832 "dependencies": { 6795 6833 "detect-libc": "^2.0.3" ··· 6802 6840 "url": "https://opencollective.com/parcel" 6803 6841 }, 6804 6842 "optionalDependencies": { 6805 - "lightningcss-darwin-arm64": "1.30.1", 6806 - "lightningcss-darwin-x64": "1.30.1", 6807 - "lightningcss-freebsd-x64": "1.30.1", 6808 - "lightningcss-linux-arm-gnueabihf": "1.30.1", 6809 - "lightningcss-linux-arm64-gnu": "1.30.1", 6810 - "lightningcss-linux-arm64-musl": "1.30.1", 6811 - "lightningcss-linux-x64-gnu": "1.30.1", 6812 - "lightningcss-linux-x64-musl": "1.30.1", 6813 - "lightningcss-win32-arm64-msvc": "1.30.1", 6814 - "lightningcss-win32-x64-msvc": "1.30.1" 6843 + "lightningcss-android-arm64": "1.30.2", 6844 + "lightningcss-darwin-arm64": "1.30.2", 6845 + "lightningcss-darwin-x64": "1.30.2", 6846 + "lightningcss-freebsd-x64": "1.30.2", 6847 + "lightningcss-linux-arm-gnueabihf": "1.30.2", 6848 + "lightningcss-linux-arm64-gnu": "1.30.2", 6849 + "lightningcss-linux-arm64-musl": "1.30.2", 6850 + "lightningcss-linux-x64-gnu": "1.30.2", 6851 + "lightningcss-linux-x64-musl": "1.30.2", 6852 + "lightningcss-win32-arm64-msvc": "1.30.2", 6853 + "lightningcss-win32-x64-msvc": "1.30.2" 6854 + } 6855 + }, 6856 + "node_modules/lightningcss-android-arm64": { 6857 + "version": "1.30.2", 6858 + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", 6859 + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", 6860 + "cpu": [ 6861 + "arm64" 6862 + ], 6863 + "license": "MPL-2.0", 6864 + "optional": true, 6865 + "os": [ 6866 + "android" 6867 + ], 6868 + "engines": { 6869 + "node": ">= 12.0.0" 6870 + }, 6871 + "funding": { 6872 + "type": "opencollective", 6873 + "url": "https://opencollective.com/parcel" 6815 6874 } 6816 6875 }, 6817 6876 "node_modules/lightningcss-darwin-arm64": { 6818 - "version": "1.30.1", 6819 - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", 6820 - "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", 6877 + "version": "1.30.2", 6878 + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", 6879 + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", 6821 6880 "cpu": [ 6822 6881 "arm64" 6823 6882 ], ··· 6835 6894 } 6836 6895 }, 6837 6896 "node_modules/lightningcss-darwin-x64": { 6838 - "version": "1.30.1", 6839 - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", 6840 - "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", 6897 + "version": "1.30.2", 6898 + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", 6899 + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", 6841 6900 "cpu": [ 6842 6901 "x64" 6843 6902 ], ··· 6855 6914 } 6856 6915 }, 6857 6916 "node_modules/lightningcss-freebsd-x64": { 6858 - "version": "1.30.1", 6859 - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", 6860 - "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", 6917 + "version": "1.30.2", 6918 + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", 6919 + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", 6861 6920 "cpu": [ 6862 6921 "x64" 6863 6922 ], ··· 6875 6934 } 6876 6935 }, 6877 6936 "node_modules/lightningcss-linux-arm-gnueabihf": { 6878 - "version": "1.30.1", 6879 - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", 6880 - "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", 6937 + "version": "1.30.2", 6938 + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", 6939 + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", 6881 6940 "cpu": [ 6882 6941 "arm" 6883 6942 ], ··· 6895 6954 } 6896 6955 }, 6897 6956 "node_modules/lightningcss-linux-arm64-gnu": { 6898 - "version": "1.30.1", 6899 - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", 6900 - "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", 6957 + "version": "1.30.2", 6958 + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", 6959 + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", 6901 6960 "cpu": [ 6902 6961 "arm64" 6903 6962 ], ··· 6915 6974 } 6916 6975 }, 6917 6976 "node_modules/lightningcss-linux-arm64-musl": { 6918 - "version": "1.30.1", 6919 - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", 6920 - "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", 6977 + "version": "1.30.2", 6978 + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", 6979 + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", 6921 6980 "cpu": [ 6922 6981 "arm64" 6923 6982 ], ··· 6935 6994 } 6936 6995 }, 6937 6996 "node_modules/lightningcss-linux-x64-gnu": { 6938 - "version": "1.30.1", 6939 - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", 6940 - "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", 6997 + "version": "1.30.2", 6998 + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", 6999 + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", 6941 7000 "cpu": [ 6942 7001 "x64" 6943 7002 ], ··· 6955 7014 } 6956 7015 }, 6957 7016 "node_modules/lightningcss-linux-x64-musl": { 6958 - "version": "1.30.1", 6959 - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", 6960 - "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", 7017 + "version": "1.30.2", 7018 + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", 7019 + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", 6961 7020 "cpu": [ 6962 7021 "x64" 6963 7022 ], ··· 6975 7034 } 6976 7035 }, 6977 7036 "node_modules/lightningcss-win32-arm64-msvc": { 6978 - "version": "1.30.1", 6979 - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", 6980 - "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", 7037 + "version": "1.30.2", 7038 + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", 7039 + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", 6981 7040 "cpu": [ 6982 7041 "arm64" 6983 7042 ], ··· 6995 7054 } 6996 7055 }, 6997 7056 "node_modules/lightningcss-win32-x64-msvc": { 6998 - "version": "1.30.1", 6999 - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", 7000 - "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", 7057 + "version": "1.30.2", 7058 + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", 7059 + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", 7001 7060 "cpu": [ 7002 7061 "x64" 7003 7062 ], ··· 7571 7630 "hermes-estree": "0.32.0" 7572 7631 } 7573 7632 }, 7574 - "node_modules/metro/node_modules/ws": { 7575 - "version": "7.5.10", 7576 - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", 7577 - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", 7578 - "license": "MIT", 7579 - "engines": { 7580 - "node": ">=8.3.0" 7581 - }, 7582 - "peerDependencies": { 7583 - "bufferutil": "^4.0.1", 7584 - "utf-8-validate": "^5.0.2" 7585 - }, 7586 - "peerDependenciesMeta": { 7587 - "bufferutil": { 7588 - "optional": true 7589 - }, 7590 - "utf-8-validate": { 7591 - "optional": true 7592 - } 7593 - } 7594 - }, 7595 7633 "node_modules/micromatch": { 7596 7634 "version": "4.0.8", 7597 7635 "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", ··· 7852 7890 } 7853 7891 }, 7854 7892 "node_modules/npm-package-arg/node_modules/semver": { 7855 - "version": "7.7.2", 7856 - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", 7857 - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", 7893 + "version": "7.7.3", 7894 + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", 7895 + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", 7858 7896 "license": "ISC", 7859 7897 "bin": { 7860 7898 "semver": "bin/semver.js" ··· 8640 8678 "ws": "^7" 8641 8679 } 8642 8680 }, 8643 - "node_modules/react-devtools-core/node_modules/ws": { 8644 - "version": "7.5.10", 8645 - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", 8646 - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", 8647 - "license": "MIT", 8648 - "engines": { 8649 - "node": ">=8.3.0" 8650 - }, 8651 - "peerDependencies": { 8652 - "bufferutil": "^4.0.1", 8653 - "utf-8-validate": "^5.0.2" 8654 - }, 8655 - "peerDependenciesMeta": { 8656 - "bufferutil": { 8657 - "optional": true 8658 - }, 8659 - "utf-8-validate": { 8660 - "optional": true 8661 - } 8662 - } 8663 - }, 8664 8681 "node_modules/react-dom": { 8665 8682 "version": "19.1.0", 8666 8683 "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", ··· 8802 8819 "resolved": "https://registry.npmjs.org/react-native-get-random-values/-/react-native-get-random-values-1.11.0.tgz", 8803 8820 "integrity": "sha512-4BTbDbRmS7iPdhYLRcz3PGFIpFJBwNZg9g42iwa2P6FOv9vZj/xJc678RZXnLNZzd0qd7Q3CCF6Yd+CU2eoXKQ==", 8804 8821 "license": "MIT", 8805 - "peer": true, 8806 8822 "dependencies": { 8807 8823 "fast-base64-decode": "^1.0.0" 8808 8824 }, ··· 8835 8851 } 8836 8852 }, 8837 8853 "node_modules/react-native-reanimated": { 8838 - "version": "4.1.0", 8839 - "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.1.0.tgz", 8840 - "integrity": "sha512-L8FqZn8VjZyBaCUMYFyx1Y+T+ZTbblaudpxReOXJ66RnOf52g6UM4Pa/IjwLD1XAw1FUxLRQrtpdjbkEc74FiQ==", 8854 + "version": "4.1.3", 8855 + "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.1.3.tgz", 8856 + "integrity": "sha512-GP8wsi1u3nqvC1fMab/m8gfFwFyldawElCcUSBJQgfrXeLmsPPUOpDw44lbLeCpcwUuLa05WTVePdTEwCLTUZg==", 8841 8857 "license": "MIT", 8842 8858 "dependencies": { 8843 8859 "react-native-is-edge-to-edge": "^1.2.1", ··· 9726 9742 "plist": "^3.0.5" 9727 9743 } 9728 9744 }, 9729 - "node_modules/simple-plist/node_modules/bplist-parser": { 9730 - "version": "0.3.1", 9731 - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz", 9732 - "integrity": "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==", 9733 - "license": "MIT", 9734 - "dependencies": { 9735 - "big-integer": "1.6.x" 9736 - }, 9737 - "engines": { 9738 - "node": ">= 5.10.0" 9739 - } 9740 - }, 9741 9745 "node_modules/simple-swizzle": { 9742 9746 "version": "0.2.2", 9743 9747 "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", ··· 10424 10428 "license": "MIT" 10425 10429 }, 10426 10430 "node_modules/undici": { 10427 - "version": "6.21.3", 10428 - "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz", 10429 - "integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==", 10431 + "version": "6.22.0", 10432 + "resolved": "https://registry.npmjs.org/undici/-/undici-6.22.0.tgz", 10433 + "integrity": "sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==", 10430 10434 "license": "MIT", 10431 10435 "engines": { 10432 10436 "node": ">=18.17" ··· 10824 10828 "license": "ISC" 10825 10829 }, 10826 10830 "node_modules/ws": { 10827 - "version": "8.18.3", 10828 - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", 10829 - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", 10831 + "version": "7.5.10", 10832 + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", 10833 + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", 10830 10834 "license": "MIT", 10831 10835 "engines": { 10832 - "node": ">=10.0.0" 10836 + "node": ">=8.3.0" 10833 10837 }, 10834 10838 "peerDependencies": { 10835 10839 "bufferutil": "^4.0.1", 10836 - "utf-8-validate": ">=5.0.2" 10840 + "utf-8-validate": "^5.0.2" 10837 10841 }, 10838 10842 "peerDependenciesMeta": { 10839 10843 "bufferutil": {
+5 -3
package.json
··· 19 19 "@react-navigation/stack": "^7.4.8", 20 20 "@ronradtke/react-native-markdown-display": "^8.1.0", 21 21 "axios": "^1.11.0", 22 - "expo": "^54.0.0", 22 + "expo": "54.0.13", 23 23 "expo-clipboard": "~8.0.7", 24 - "expo-font": "~14.0.8", 24 + "expo-font": "~14.0.9", 25 25 "expo-image-picker": "~17.0.8", 26 26 "expo-secure-store": "~15.0.7", 27 27 "expo-status-bar": "~3.0.8", 28 + "expo-system-ui": "~6.0.7", 28 29 "lottie-react-native": "~7.3.1", 29 30 "react": "19.1.0", 30 31 "react-dom": "19.1.0", 31 32 "react-native": "0.81.4", 32 33 "react-native-gesture-handler": "~2.28.0", 34 + "react-native-get-random-values": "^1.11.0", 33 35 "react-native-polyfill-globals": "^3.1.0", 34 - "react-native-reanimated": "~4.1.0", 36 + "react-native-reanimated": "~4.1.1", 35 37 "react-native-safe-area-context": "~5.6.0", 36 38 "react-native-screens": "~4.16.0", 37 39 "react-native-svg": "15.12.1",
+27
polyfills.js
··· 1 + /** 2 + * Polyfills for React Native to support Web Streams API and Crypto 3 + * Required for Letta SDK streaming functionality 4 + */ 5 + 6 + // IMPORTANT: Import crypto polyfill FIRST before anything else 7 + // This provides secure random number generation required by many libraries 8 + import 'react-native-get-random-values'; 9 + 10 + // Only apply polyfills in React Native environment (not web) 11 + if (typeof global !== 'undefined' && !global.ReadableStream) { 12 + const { ReadableStream, WritableStream, TransformStream } = require('web-streams-polyfill'); 13 + 14 + global.ReadableStream = ReadableStream; 15 + global.WritableStream = WritableStream; 16 + global.TransformStream = TransformStream; 17 + 18 + // Also polyfill TextEncoder/TextDecoder which are often needed with streams 19 + if (!global.TextEncoder) { 20 + global.TextEncoder = require('text-encoding').TextEncoder; 21 + } 22 + if (!global.TextDecoder) { 23 + global.TextDecoder = require('text-encoding').TextDecoder; 24 + } 25 + 26 + console.log('[Polyfill] Web Streams API polyfill loaded'); 27 + }
-106
src/components/ChatInput.tsx
··· 1 - import React, { useState } from 'react'; 2 - import { View, TextInput, TouchableOpacity, StyleSheet } from 'react-native'; 3 - import { darkTheme } from '../theme'; 4 - import { Ionicons } from '@expo/vector-icons'; 5 - 6 - interface ChatInputProps { 7 - onSendMessage: (message: string) => void; 8 - disabled?: boolean; 9 - placeholder?: string; 10 - } 11 - 12 - const ChatInput: React.FC<ChatInputProps> = ({ 13 - onSendMessage, 14 - disabled = false, 15 - placeholder = "Type a message..." 16 - }) => { 17 - const [message, setMessage] = useState(''); 18 - 19 - const handleSend = () => { 20 - const trimmedMessage = message.trim(); 21 - if (trimmedMessage && !disabled) { 22 - onSendMessage(trimmedMessage); 23 - setMessage(''); 24 - } 25 - }; 26 - 27 - const canSend = message.trim().length > 0 && !disabled; 28 - 29 - return ( 30 - <View style={styles.container}> 31 - <View style={styles.inputContainer}> 32 - <TextInput 33 - style={[styles.textInput, disabled && styles.disabledInput]} 34 - value={message} 35 - onChangeText={setMessage} 36 - placeholder={placeholder} 37 - placeholderTextColor={darkTheme.colors.text.secondary} 38 - multiline 39 - maxLength={2000} 40 - editable={!disabled} 41 - onSubmitEditing={handleSend} 42 - blurOnSubmit={false} 43 - /> 44 - <TouchableOpacity 45 - style={[styles.sendButton, canSend && styles.sendButtonActive]} 46 - onPress={handleSend} 47 - disabled={!canSend} 48 - activeOpacity={0.7} 49 - > 50 - <Ionicons 51 - name="send" 52 - size={20} 53 - color={canSend ? darkTheme.colors.text.inverse : darkTheme.colors.text.secondary} 54 - /> 55 - </TouchableOpacity> 56 - </View> 57 - </View> 58 - ); 59 - }; 60 - 61 - const styles = StyleSheet.create({ 62 - container: { 63 - paddingHorizontal: 16, 64 - paddingVertical: 12, 65 - backgroundColor: darkTheme.colors.background.tertiary, 66 - borderTopWidth: 1, 67 - borderTopColor: darkTheme.colors.border.primary, 68 - }, 69 - inputContainer: { 70 - flexDirection: 'row', 71 - alignItems: 'flex-end', 72 - backgroundColor: darkTheme.colors.background.surface, 73 - borderRadius: 20, 74 - paddingHorizontal: 16, 75 - paddingVertical: 8, 76 - minHeight: 40, 77 - borderWidth: 0, 78 - }, 79 - textInput: { 80 - flex: 1, 81 - fontSize: 16, 82 - color: darkTheme.colors.text.primary, 83 - backgroundColor: 'transparent', 84 - maxHeight: 100, 85 - paddingVertical: 8, 86 - borderWidth: 0, 87 - outline: 'none', 88 - }, 89 - disabledInput: { 90 - opacity: 0.6, 91 - }, 92 - sendButton: { 93 - width: 36, 94 - height: 36, 95 - borderRadius: 18, 96 - backgroundColor: darkTheme.colors.border.primary, 97 - alignItems: 'center', 98 - justifyContent: 'center', 99 - marginLeft: 8, 100 - }, 101 - sendButtonActive: { 102 - backgroundColor: darkTheme.colors.interactive.primary, 103 - }, 104 - }); 105 - 106 - export default React.memo(ChatInput);
+6 -5
src/components/LiveStatusIndicator.tsx
··· 1 1 import React, { useEffect, useRef } from 'react'; 2 2 import { View, Text, Animated, StyleSheet } from 'react-native'; 3 - import { darkTheme } from '../theme'; 3 + import { darkTheme, lightTheme } from '../theme'; 4 4 5 5 interface LiveStatusIndicatorProps { 6 6 status: string; // e.g., "thinking", "searching the web", "saying", "thought" 7 + isDark?: boolean; 7 8 } 8 9 9 - const LiveStatusIndicator: React.FC<LiveStatusIndicatorProps> = ({ status }) => { 10 + const LiveStatusIndicator: React.FC<LiveStatusIndicatorProps> = ({ status, isDark = true }) => { 11 + const theme = isDark ? darkTheme : lightTheme; 10 12 const rainbowAnimValue = useRef(new Animated.Value(0)).current; 11 13 12 14 // Animate rainbow gradient ··· 29 31 30 32 return ( 31 33 <View style={styles.container}> 32 - <Text style={styles.text}>(</Text> 34 + <Text style={[styles.text, { color: theme.colors.text.primary }]}>(</Text> 33 35 <Animated.Text 34 36 style={[ 35 37 styles.coText, ··· 43 45 > 44 46 co 45 47 </Animated.Text> 46 - <Text style={styles.text}> {displayText})</Text> 48 + <Text style={[styles.text, { color: theme.colors.text.primary }]}> {displayText})</Text> 47 49 </View> 48 50 ); 49 51 }; ··· 58 60 text: { 59 61 fontSize: 24, 60 62 fontFamily: 'Lexend_400Regular', 61 - color: darkTheme.colors.text.primary, 62 63 }, 63 64 coText: { 64 65 fontSize: 24,
+2 -2
src/components/MemoryBlockViewer.tsx
··· 106 106 {block.description} 107 107 </Text> 108 108 )} 109 - <View style={styles.divider} /> 109 + <View style={[styles.divider, { backgroundColor: theme.colors.border.primary }]} /> 110 110 <MessageContent content={block.value} isUser={false} isDark={isDark} /> 111 111 </View> 112 112 </ScrollView> ··· 170 170 {block.description} 171 171 </Text> 172 172 )} 173 - <View style={styles.divider} /> 173 + <View style={[styles.divider, { backgroundColor: theme.colors.border.primary }]} /> 174 174 <MessageContent content={block.value} isUser={false} isDark={isDark} /> 175 175 </View> 176 176 </ScrollView>
+21 -4
src/components/MessageInput.tsx
··· 1 - import React, { useState, useEffect } from 'react'; 1 + import React, { useState, useEffect, useRef } from 'react'; 2 2 import { TextInput, StyleSheet, Platform } from 'react-native'; 3 3 4 4 interface MessageInputProps { ··· 19 19 clearTrigger, 20 20 }) => { 21 21 const [inputText, setInputText] = useState(''); 22 + const inputRef = useRef<any>(null); 22 23 23 24 useEffect(() => { 24 25 if (clearTrigger > 0) { ··· 46 47 } 47 48 ], [colorScheme]); 48 49 50 + const handleContentSizeChange = React.useCallback((event: any) => { 51 + if (Platform.OS !== 'web') { 52 + // Native platforms can use onContentSizeChange 53 + const contentHeight = event.nativeEvent.contentSize.height; 54 + const newHeight = Math.min(Math.max(contentHeight, 40), 120); 55 + if (inputRef.current) { 56 + inputRef.current.setNativeProps({ style: { height: newHeight } }); 57 + } 58 + } 59 + }, []); 60 + 49 61 const handleFocus = React.useCallback(() => onFocusChange(true), [onFocusChange]); 50 62 const handleBlur = React.useCallback(() => onFocusChange(false), [onFocusChange]); 51 63 52 64 return ( 53 65 <TextInput 66 + ref={inputRef} 54 67 style={inputStyle} 55 68 placeholder="What's on your mind?" 56 69 placeholderTextColor={colorScheme === 'dark' ? '#666666' : '#999999'} ··· 63 76 editable={!isSendingMessage} 64 77 autoFocus 65 78 onSubmitEditing={handleSubmit} 79 + onContentSizeChange={handleContentSizeChange} 66 80 /> 67 81 ); 68 82 }; ··· 70 84 const styles = StyleSheet.create({ 71 85 textInput: { 72 86 width: '100%', 73 - height: 48, 87 + minHeight: 40, 88 + maxHeight: 120, 74 89 paddingLeft: 18, 75 90 paddingRight: 130, 76 - paddingTop: 12, 77 - paddingBottom: 12, 91 + paddingTop: 8, 92 + paddingBottom: 8, 78 93 borderRadius: 24, 79 94 fontSize: 16, 80 95 lineHeight: 24, ··· 84 99 outline: 'none', 85 100 WebkitAppearance: 'none', 86 101 MozAppearance: 'none', 102 + resize: 'none', 103 + overflowY: 'auto', 87 104 }), 88 105 }, 89 106 });
+14 -34
src/components/ReasoningToggle.tsx
··· 1 - import React, { useState, useEffect, useRef } from 'react'; 2 - import { View, Text, TouchableOpacity, StyleSheet, Animated } from 'react-native'; 1 + import React, { useState } from 'react'; 2 + import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'; 3 3 import { Ionicons } from '@expo/vector-icons'; 4 - import { darkTheme } from '../theme'; 4 + import { darkTheme, lightTheme } from '../theme'; 5 5 6 6 interface ReasoningToggleProps { 7 7 reasoning: string; ··· 10 10 onToggle?: () => void; 11 11 customToggleContent?: React.ReactNode; 12 12 hideChevron?: boolean; 13 + isDark?: boolean; 13 14 } 14 15 15 16 const ReasoningToggle: React.FC<ReasoningToggleProps> = ({ ··· 18 19 isExpanded: externalExpanded, 19 20 onToggle: externalOnToggle, 20 21 customToggleContent, 21 - hideChevron = false 22 + hideChevron = false, 23 + isDark = true 22 24 }) => { 25 + const theme = isDark ? darkTheme : lightTheme; 23 26 const [internalExpanded, setInternalExpanded] = useState(false); 24 - const rainbowAnimValue = useRef(new Animated.Value(0)).current; 25 27 26 28 // Use external state if provided, otherwise use internal 27 29 const isExpanded = externalExpanded !== undefined ? externalExpanded : internalExpanded; 28 30 const handleToggle = externalOnToggle || (() => setInternalExpanded(!internalExpanded)); 29 31 30 - // Animate rainbow gradient when reasoning is expanded 31 - useEffect(() => { 32 - if (isExpanded) { 33 - rainbowAnimValue.setValue(0); 34 - const animation = Animated.loop( 35 - Animated.timing(rainbowAnimValue, { 36 - toValue: 1, 37 - duration: 3000, 38 - useNativeDriver: false, 39 - }) 40 - ); 41 - animation.start(); 42 - return () => animation.stop(); 43 - } 44 - }, [isExpanded]); 45 - 46 32 return ( 47 33 <> 48 34 <TouchableOpacity ··· 53 39 customToggleContent 54 40 ) : ( 55 41 <> 56 - <Text style={styles.reasoningToggleText}>(co thought)</Text> 42 + <Text style={[styles.reasoningToggleText, { color: theme.colors.text.primary }]}>(co thought)</Text> 57 43 {!hideChevron && ( 58 44 <Ionicons 59 45 name={isExpanded ? "chevron-up" : "chevron-down"} 60 46 size={18} 61 - color={darkTheme.colors.text.tertiary} 47 + color={theme.colors.text.tertiary} 62 48 style={{ marginLeft: 4 }} 63 49 /> 64 50 )} ··· 66 52 )} 67 53 </TouchableOpacity> 68 54 {isExpanded && ( 69 - <Animated.View style={[ 55 + <View style={[ 70 56 styles.reasoningExpandedContainer, 71 57 { 72 - borderLeftColor: rainbowAnimValue.interpolate({ 73 - inputRange: [0, 0.2, 0.4, 0.6, 0.8, 1], 74 - outputRange: ['#FF6B6B', '#FFD93D', '#6BCF7F', '#4D96FF', '#9D4EDD', '#FF6B6B'] 75 - }), 58 + backgroundColor: isDark ? 'rgba(255, 255, 255, 0.04)' : 'rgba(0, 0, 0, 0.04)', 59 + borderLeftColor: theme.colors.border.primary, 76 60 } 77 61 ]}> 78 - <Text style={styles.reasoningExpandedText}>{reasoning}</Text> 79 - </Animated.View> 62 + <Text style={[styles.reasoningExpandedText, { color: theme.colors.text.primary }]}>{reasoning}</Text> 63 + </View> 80 64 )} 81 65 </> 82 66 ); ··· 92 76 reasoningToggleText: { 93 77 fontSize: 16, 94 78 fontFamily: 'Lexend_500Medium', 95 - color: darkTheme.colors.text.secondary, 96 79 }, 97 80 reasoningExpandedContainer: { 98 81 paddingVertical: 12, 99 82 paddingHorizontal: 16, 100 83 paddingLeft: 20, 101 84 marginBottom: 12, 102 - backgroundColor: 'rgba(255, 255, 255, 0.04)', 103 85 borderRadius: 8, 104 86 borderLeftWidth: 4, 105 - borderLeftColor: '#555555', 106 87 overflow: 'hidden', 107 88 }, 108 89 reasoningExpandedText: { 109 90 fontSize: 14, 110 91 fontFamily: 'Lexend_400Regular', 111 - color: darkTheme.colors.text.secondary, 112 92 lineHeight: 22, 113 93 fontStyle: 'normal', 114 94 },
+23 -21
src/components/ToolCallItem.tsx
··· 1 1 import React, { useMemo, useState } from 'react'; 2 - import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'; 2 + import { View, Text, TouchableOpacity, StyleSheet, Platform } from 'react-native'; 3 3 import { Ionicons } from '@expo/vector-icons'; 4 - import { darkTheme } from '../theme'; 4 + import { darkTheme, lightTheme } from '../theme'; 5 5 import ReasoningToggle from './ReasoningToggle'; 6 6 7 7 interface ToolCallItemProps { ··· 9 9 resultText?: string; 10 10 reasoning?: string; 11 11 hasResult?: boolean; 12 + isDark?: boolean; 12 13 } 13 14 14 15 // Extract parameters for contextual display ··· 62 63 return displayNames[toolName] || { present: toolName, past: toolName }; 63 64 }; 64 65 65 - const ToolCallItem: React.FC<ToolCallItemProps> = ({ callText, resultText, reasoning, hasResult = false }) => { 66 + const ToolCallItem: React.FC<ToolCallItemProps> = ({ callText, resultText, reasoning, hasResult = false, isDark = true }) => { 67 + const theme = isDark ? darkTheme : lightTheme; 66 68 const [expanded, setExpanded] = useState(false); 67 69 const [resultExpanded, setResultExpanded] = useState(false); 68 70 ··· 134 136 135 137 return ( 136 138 <View style={styles.container}> 137 - {reasoning && <ReasoningToggle reasoning={reasoning} />} 139 + {reasoning && <ReasoningToggle reasoning={reasoning} isDark={isDark} />} 138 140 <TouchableOpacity 139 141 style={styles.header} 140 142 onPress={() => setExpanded((e) => !e)} 141 143 activeOpacity={0.7} 142 144 > 143 - <Text style={expanded ? styles.callText : styles.displayName} numberOfLines={expanded ? 0 : 1}> 145 + <Text style={[expanded ? styles.callText : styles.displayName, { color: expanded ? theme.colors.text.primary : theme.colors.text.primary }]} numberOfLines={expanded ? 0 : 1}> 144 146 {expanded ? prettyCallText : `(${displayText})`} 145 147 </Text> 146 148 <Ionicons 147 149 name={expanded ? 'chevron-up' : 'chevron-down'} 148 150 size={18} 149 - color={darkTheme.colors.text.tertiary} 151 + color={theme.colors.text.tertiary} 150 152 style={styles.chevron} 151 153 /> 152 154 </TouchableOpacity> 153 155 {!!resultText && ( 154 156 <TouchableOpacity 155 - style={[styles.resultHeader, resultExpanded && styles.resultHeaderExpanded]} 157 + style={[styles.resultHeader, resultExpanded && styles.resultHeaderExpanded, { backgroundColor: theme.colors.background.secondary, borderColor: theme.colors.border.primary }]} 156 158 onPress={() => setResultExpanded((e) => !e)} 157 159 activeOpacity={0.7} 158 160 > 159 161 <Ionicons 160 162 name={resultExpanded ? 'chevron-down' : 'chevron-forward'} 161 163 size={12} 162 - color={darkTheme.colors.text.tertiary} 164 + color={theme.colors.text.tertiary} 163 165 style={styles.resultChevron} 164 166 /> 165 - <Text style={styles.resultLabel}>Result</Text> 167 + <Text style={[styles.resultLabel, { color: theme.colors.text.tertiary }]}>Result</Text> 166 168 </TouchableOpacity> 167 169 )} 168 170 {resultExpanded && !!resultText && ( 169 - <View style={styles.resultBox}> 170 - <Text style={styles.resultText}>{formattedResult}</Text> 171 + <View style={[styles.resultBox, { backgroundColor: theme.colors.background.tertiary, borderColor: theme.colors.border.primary }]}> 172 + <Text style={[styles.resultText, { color: theme.colors.text.primary }]}>{formattedResult}</Text> 171 173 </View> 172 174 )} 173 175 </View> ··· 190 192 displayName: { 191 193 fontSize: 16, 192 194 fontFamily: 'Lexend_500Medium', 193 - color: darkTheme.colors.text.secondary, 194 195 flexShrink: 1, 195 196 }, 196 197 callText: { 197 - color: darkTheme.colors.text.primary, 198 - fontFamily: 'Menlo', 198 + fontFamily: Platform.select({ 199 + ios: 'Menlo', 200 + android: 'monospace', 201 + default: 'monospace', 202 + }), 199 203 fontSize: 13, 200 204 lineHeight: 18, 201 205 flexShrink: 1, ··· 206 210 flexDirection: 'row', 207 211 alignItems: 'center', 208 212 gap: 6, 209 - backgroundColor: '#242424', 210 213 borderLeftWidth: 1, 211 214 borderRightWidth: 1, 212 - borderColor: 'rgba(255, 255, 255, 0.1)', 213 215 paddingVertical: 8, 214 216 paddingHorizontal: 10, 215 217 }, ··· 220 222 marginTop: 1, 221 223 }, 222 224 resultLabel: { 223 - color: darkTheme.colors.text.tertiary, 224 225 fontSize: 12, 225 226 }, 226 227 resultBox: { 227 - backgroundColor: '#1E1E1E', 228 228 borderBottomLeftRadius: 10, 229 229 borderBottomRightRadius: 10, 230 230 borderLeftWidth: 1, 231 231 borderRightWidth: 1, 232 232 borderBottomWidth: 1, 233 - borderColor: 'rgba(255, 255, 255, 0.1)', 234 233 paddingVertical: 10, 235 234 paddingHorizontal: 12, 236 235 }, 237 236 resultText: { 238 - color: darkTheme.colors.text.primary, 239 237 fontSize: 14, 240 238 lineHeight: 20, 241 239 whiteSpace: 'pre-wrap' as any, 242 - fontFamily: 'Menlo', 240 + fontFamily: Platform.select({ 241 + ios: 'Menlo', 242 + android: 'monospace', 243 + default: 'monospace', 244 + }), 243 245 }, 244 246 }); 245 247