clawdex-mobile 2.0.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/pages.yml +41 -0
- package/AGENTS.md +263 -110
- package/README.md +1 -1
- package/apps/mobile/.env.example +2 -2
- package/apps/mobile/App.tsx +175 -14
- package/apps/mobile/app.json +27 -9
- package/apps/mobile/eas.json +14 -4
- package/apps/mobile/package.json +13 -13
- package/apps/mobile/src/api/__tests__/chatMapping.test.ts +219 -0
- package/apps/mobile/src/api/__tests__/client.test.ts +579 -6
- package/apps/mobile/src/api/__tests__/ws.test.ts +27 -0
- package/apps/mobile/src/api/account.ts +47 -0
- package/apps/mobile/src/api/chatMapping.ts +435 -18
- package/apps/mobile/src/api/client.ts +296 -36
- package/apps/mobile/src/api/rateLimits.ts +143 -0
- package/apps/mobile/src/api/types.ts +106 -0
- package/apps/mobile/src/api/ws.ts +10 -1
- package/apps/mobile/src/components/ChatHeader.tsx +12 -12
- package/apps/mobile/src/components/ChatInput.tsx +154 -88
- package/apps/mobile/src/components/ChatMessage.tsx +548 -93
- package/apps/mobile/src/components/ComposerUsageLimits.tsx +167 -0
- package/apps/mobile/src/components/SelectionSheet.tsx +466 -0
- package/apps/mobile/src/components/ToolBlock.tsx +17 -15
- package/apps/mobile/src/components/VoiceRecordingWaveform.tsx +181 -0
- package/apps/mobile/src/components/WorkspacePickerModal.tsx +572 -0
- package/apps/mobile/src/components/__tests__/chat-input-layout.test.ts +35 -0
- package/apps/mobile/src/components/__tests__/chatImageSource.test.ts +44 -0
- package/apps/mobile/src/components/__tests__/composerUsageLimits.test.ts +138 -0
- package/apps/mobile/src/components/__tests__/voiceWaveform.test.ts +31 -0
- package/apps/mobile/src/components/chat-input-layout.ts +59 -0
- package/apps/mobile/src/components/chatImageSource.ts +86 -0
- package/apps/mobile/src/components/usageLimitBadges.ts +109 -0
- package/apps/mobile/src/components/voiceWaveform.ts +46 -0
- package/apps/mobile/src/config.ts +9 -2
- package/apps/mobile/src/hooks/useVoiceRecorder.ts +8 -1
- package/apps/mobile/src/navigation/DrawerContent.tsx +607 -457
- package/apps/mobile/src/navigation/__tests__/chatThreadTree.test.ts +89 -0
- package/apps/mobile/src/navigation/__tests__/drawerChats.test.ts +65 -0
- package/apps/mobile/src/navigation/chatThreadTree.ts +191 -0
- package/apps/mobile/src/navigation/drawerChats.ts +9 -0
- package/apps/mobile/src/screens/GitScreen.tsx +2 -0
- package/apps/mobile/src/screens/MainScreen.tsx +4244 -1237
- package/apps/mobile/src/screens/OnboardingScreen.tsx +2 -0
- package/apps/mobile/src/screens/SettingsScreen.tsx +256 -226
- package/apps/mobile/src/screens/TerminalScreen.tsx +2 -5
- package/apps/mobile/src/screens/__tests__/agentThreadDisplay.test.ts +80 -0
- package/apps/mobile/src/screens/__tests__/agentThreads.test.ts +170 -0
- package/apps/mobile/src/screens/__tests__/planCardState.test.ts +88 -0
- package/apps/mobile/src/screens/__tests__/subAgentTranscript.test.ts +102 -0
- package/apps/mobile/src/screens/__tests__/transcriptMessages.test.ts +97 -0
- package/apps/mobile/src/screens/agentThreadDisplay.ts +261 -0
- package/apps/mobile/src/screens/agentThreads.ts +167 -0
- package/apps/mobile/src/screens/planCardState.ts +40 -0
- package/apps/mobile/src/screens/subAgentTranscript.ts +149 -0
- package/apps/mobile/src/screens/transcriptMessages.ts +102 -0
- package/apps/mobile/src/theme.ts +6 -12
- package/docs/codex-app-server-cli-gap-tracker.md +14 -5
- package/docs/privacy-policy.md +54 -0
- package/docs/setup-and-operations.md +4 -3
- package/docs/terms-of-service.md +33 -0
- package/package.json +3 -3
- package/services/mac-bridge/package.json +6 -6
- package/services/rust-bridge/Cargo.lock +56 -47
- package/services/rust-bridge/Cargo.toml +1 -1
- package/services/rust-bridge/package.json +1 -1
- package/services/rust-bridge/src/main.rs +507 -9
- package/site/index.html +54 -0
- package/site/privacy/index.html +80 -0
- package/site/styles.css +135 -0
- package/site/support/index.html +51 -0
- package/site/terms/index.html +68 -0
package/apps/mobile/App.tsx
CHANGED
|
@@ -38,6 +38,7 @@ const SWIPE_OPEN_DISTANCE = 56;
|
|
|
38
38
|
const SWIPE_CLOSE_DISTANCE = 56;
|
|
39
39
|
const SWIPE_OPEN_VELOCITY = 0.4;
|
|
40
40
|
const SWIPE_CLOSE_VELOCITY = -0.4;
|
|
41
|
+
const DRAWER_CONTENT_SCALE = 0.94;
|
|
41
42
|
const APP_SETTINGS_FILE = 'clawdex-app-settings.json';
|
|
42
43
|
const APP_SETTINGS_VERSION = 3;
|
|
43
44
|
|
|
@@ -79,10 +80,22 @@ export default function App() {
|
|
|
79
80
|
const [defaultReasoningEffort, setDefaultReasoningEffort] =
|
|
80
81
|
useState<ReasoningEffort | null>(null);
|
|
81
82
|
const [approvalMode, setApprovalMode] = useState<ApprovalMode>('normal');
|
|
83
|
+
const [showToolCalls, setShowToolCalls] = useState(false);
|
|
82
84
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
83
85
|
const drawerAnim = useRef(new Animated.Value(-DRAWER_WIDTH)).current;
|
|
84
86
|
const overlayAnim = useRef(new Animated.Value(0)).current;
|
|
85
87
|
const { width: screenWidth } = useWindowDimensions();
|
|
88
|
+
const contentShiftOpen = Math.min(DRAWER_WIDTH - 12, screenWidth * 0.74);
|
|
89
|
+
const contentTranslateX = drawerAnim.interpolate({
|
|
90
|
+
inputRange: [-DRAWER_WIDTH, 0],
|
|
91
|
+
outputRange: [0, contentShiftOpen],
|
|
92
|
+
extrapolate: 'clamp',
|
|
93
|
+
});
|
|
94
|
+
const contentScale = drawerAnim.interpolate({
|
|
95
|
+
inputRange: [-DRAWER_WIDTH, 0],
|
|
96
|
+
outputRange: [1, DRAWER_CONTENT_SCALE],
|
|
97
|
+
extrapolate: 'clamp',
|
|
98
|
+
});
|
|
86
99
|
|
|
87
100
|
useEffect(() => {
|
|
88
101
|
if (!ws) {
|
|
@@ -97,9 +110,11 @@ export default function App() {
|
|
|
97
110
|
async (
|
|
98
111
|
nextBridgeUrl: string | null,
|
|
99
112
|
nextBridgeToken: string | null,
|
|
113
|
+
nextDefaultStartCwd: string | null,
|
|
100
114
|
nextModelId: string | null,
|
|
101
115
|
nextEffort: ReasoningEffort | null,
|
|
102
|
-
nextApprovalMode: ApprovalMode
|
|
116
|
+
nextApprovalMode: ApprovalMode,
|
|
117
|
+
nextShowToolCalls: boolean
|
|
103
118
|
) => {
|
|
104
119
|
const settingsPath = getAppSettingsPath();
|
|
105
120
|
if (!settingsPath) {
|
|
@@ -110,9 +125,11 @@ export default function App() {
|
|
|
110
125
|
version: APP_SETTINGS_VERSION,
|
|
111
126
|
bridgeUrl: nextBridgeUrl,
|
|
112
127
|
bridgeToken: nextBridgeToken,
|
|
128
|
+
defaultStartCwd: nextDefaultStartCwd,
|
|
113
129
|
defaultModelId: nextModelId,
|
|
114
130
|
defaultReasoningEffort: nextEffort,
|
|
115
131
|
approvalMode: nextApprovalMode,
|
|
132
|
+
showToolCalls: nextShowToolCalls,
|
|
116
133
|
});
|
|
117
134
|
|
|
118
135
|
try {
|
|
@@ -128,9 +145,11 @@ export default function App() {
|
|
|
128
145
|
let cancelled = false;
|
|
129
146
|
|
|
130
147
|
const resetToDefaults = () => {
|
|
148
|
+
setDefaultStartCwd(null);
|
|
131
149
|
setDefaultModelId(null);
|
|
132
150
|
setDefaultReasoningEffort(null);
|
|
133
151
|
setApprovalMode('normal');
|
|
152
|
+
setShowToolCalls(false);
|
|
134
153
|
};
|
|
135
154
|
|
|
136
155
|
const loadSettings = async () => {
|
|
@@ -154,9 +173,11 @@ export default function App() {
|
|
|
154
173
|
const resolvedBridgeUrl = parsed.bridgeUrl ?? null;
|
|
155
174
|
setBridgeUrl(resolvedBridgeUrl);
|
|
156
175
|
setBridgeToken(parsed.bridgeToken ?? env.hostBridgeToken);
|
|
176
|
+
setDefaultStartCwd(parsed.defaultStartCwd);
|
|
157
177
|
setDefaultModelId(parsed.defaultModelId);
|
|
158
178
|
setDefaultReasoningEffort(parsed.defaultReasoningEffort);
|
|
159
179
|
setApprovalMode(parsed.approvalMode);
|
|
180
|
+
setShowToolCalls(parsed.showToolCalls);
|
|
160
181
|
} catch {
|
|
161
182
|
if (!cancelled) {
|
|
162
183
|
resetToDefaults();
|
|
@@ -295,6 +316,12 @@ export default function App() {
|
|
|
295
316
|
|
|
296
317
|
const handleSelectChat = useCallback(
|
|
297
318
|
(id: string) => {
|
|
319
|
+
const currentChatId = activeChat?.id ?? selectedChatId;
|
|
320
|
+
if (currentScreen === 'Main' && currentChatId === id) {
|
|
321
|
+
closeDrawer();
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
298
325
|
setSelectedChatId(id);
|
|
299
326
|
setGitChat(null);
|
|
300
327
|
setCurrentScreen('Main');
|
|
@@ -302,7 +329,7 @@ export default function App() {
|
|
|
302
329
|
setPendingMainChatSnapshot(null);
|
|
303
330
|
closeDrawer();
|
|
304
331
|
},
|
|
305
|
-
[closeDrawer]
|
|
332
|
+
[activeChat?.id, closeDrawer, currentScreen, selectedChatId]
|
|
306
333
|
);
|
|
307
334
|
|
|
308
335
|
const handleNewChat = useCallback(() => {
|
|
@@ -325,12 +352,21 @@ export default function App() {
|
|
|
325
352
|
void saveAppSettings(
|
|
326
353
|
bridgeUrl,
|
|
327
354
|
bridgeToken,
|
|
355
|
+
defaultStartCwd,
|
|
328
356
|
normalizedModelId,
|
|
329
357
|
normalizedEffort,
|
|
330
|
-
approvalMode
|
|
358
|
+
approvalMode,
|
|
359
|
+
showToolCalls
|
|
331
360
|
);
|
|
332
361
|
},
|
|
333
|
-
[
|
|
362
|
+
[
|
|
363
|
+
approvalMode,
|
|
364
|
+
bridgeToken,
|
|
365
|
+
bridgeUrl,
|
|
366
|
+
defaultStartCwd,
|
|
367
|
+
saveAppSettings,
|
|
368
|
+
showToolCalls,
|
|
369
|
+
]
|
|
334
370
|
);
|
|
335
371
|
|
|
336
372
|
const handleApprovalModeChange = useCallback(
|
|
@@ -340,12 +376,71 @@ export default function App() {
|
|
|
340
376
|
void saveAppSettings(
|
|
341
377
|
bridgeUrl,
|
|
342
378
|
bridgeToken,
|
|
379
|
+
defaultStartCwd,
|
|
380
|
+
defaultModelId,
|
|
381
|
+
defaultReasoningEffort,
|
|
382
|
+
normalizedMode,
|
|
383
|
+
showToolCalls
|
|
384
|
+
);
|
|
385
|
+
},
|
|
386
|
+
[
|
|
387
|
+
bridgeToken,
|
|
388
|
+
bridgeUrl,
|
|
389
|
+
defaultStartCwd,
|
|
390
|
+
defaultModelId,
|
|
391
|
+
defaultReasoningEffort,
|
|
392
|
+
saveAppSettings,
|
|
393
|
+
showToolCalls,
|
|
394
|
+
]
|
|
395
|
+
);
|
|
396
|
+
|
|
397
|
+
const handleShowToolCallsChange = useCallback(
|
|
398
|
+
(nextValue: boolean) => {
|
|
399
|
+
setShowToolCalls(nextValue);
|
|
400
|
+
void saveAppSettings(
|
|
401
|
+
bridgeUrl,
|
|
402
|
+
bridgeToken,
|
|
403
|
+
defaultStartCwd,
|
|
343
404
|
defaultModelId,
|
|
344
405
|
defaultReasoningEffort,
|
|
345
|
-
|
|
406
|
+
approvalMode,
|
|
407
|
+
nextValue
|
|
346
408
|
);
|
|
347
409
|
},
|
|
348
|
-
[
|
|
410
|
+
[
|
|
411
|
+
approvalMode,
|
|
412
|
+
bridgeToken,
|
|
413
|
+
bridgeUrl,
|
|
414
|
+
defaultStartCwd,
|
|
415
|
+
defaultModelId,
|
|
416
|
+
defaultReasoningEffort,
|
|
417
|
+
saveAppSettings,
|
|
418
|
+
]
|
|
419
|
+
);
|
|
420
|
+
|
|
421
|
+
const handleDefaultStartCwdChange = useCallback(
|
|
422
|
+
(nextCwd: string | null) => {
|
|
423
|
+
const normalizedDefaultStartCwd = normalizeDefaultStartCwd(nextCwd);
|
|
424
|
+
setDefaultStartCwd(normalizedDefaultStartCwd);
|
|
425
|
+
void saveAppSettings(
|
|
426
|
+
bridgeUrl,
|
|
427
|
+
bridgeToken,
|
|
428
|
+
normalizedDefaultStartCwd,
|
|
429
|
+
defaultModelId,
|
|
430
|
+
defaultReasoningEffort,
|
|
431
|
+
approvalMode,
|
|
432
|
+
showToolCalls
|
|
433
|
+
);
|
|
434
|
+
},
|
|
435
|
+
[
|
|
436
|
+
approvalMode,
|
|
437
|
+
bridgeToken,
|
|
438
|
+
bridgeUrl,
|
|
439
|
+
defaultModelId,
|
|
440
|
+
defaultReasoningEffort,
|
|
441
|
+
saveAppSettings,
|
|
442
|
+
showToolCalls,
|
|
443
|
+
]
|
|
349
444
|
);
|
|
350
445
|
|
|
351
446
|
const handleBridgeUrlSaved = useCallback(
|
|
@@ -365,9 +460,11 @@ export default function App() {
|
|
|
365
460
|
void saveAppSettings(
|
|
366
461
|
normalized,
|
|
367
462
|
normalizeBridgeToken(nextBridgeToken),
|
|
463
|
+
defaultStartCwd,
|
|
368
464
|
defaultModelId,
|
|
369
465
|
defaultReasoningEffort,
|
|
370
|
-
approvalMode
|
|
466
|
+
approvalMode,
|
|
467
|
+
showToolCalls
|
|
371
468
|
);
|
|
372
469
|
setCurrentScreen(onboardingMode === 'edit' ? onboardingReturnScreen : 'Main');
|
|
373
470
|
setOnboardingMode('edit');
|
|
@@ -376,11 +473,13 @@ export default function App() {
|
|
|
376
473
|
[
|
|
377
474
|
approvalMode,
|
|
378
475
|
closeDrawer,
|
|
476
|
+
defaultStartCwd,
|
|
379
477
|
defaultModelId,
|
|
380
478
|
defaultReasoningEffort,
|
|
381
479
|
onboardingMode,
|
|
382
480
|
onboardingReturnScreen,
|
|
383
481
|
saveAppSettings,
|
|
482
|
+
showToolCalls,
|
|
384
483
|
]
|
|
385
484
|
);
|
|
386
485
|
|
|
@@ -402,14 +501,24 @@ export default function App() {
|
|
|
402
501
|
setOnboardingMode('initial');
|
|
403
502
|
setOnboardingReturnScreen('Main');
|
|
404
503
|
setCurrentScreen('Onboarding');
|
|
405
|
-
void saveAppSettings(
|
|
504
|
+
void saveAppSettings(
|
|
505
|
+
null,
|
|
506
|
+
null,
|
|
507
|
+
defaultStartCwd,
|
|
508
|
+
defaultModelId,
|
|
509
|
+
defaultReasoningEffort,
|
|
510
|
+
approvalMode,
|
|
511
|
+
showToolCalls
|
|
512
|
+
);
|
|
406
513
|
closeDrawer();
|
|
407
514
|
}, [
|
|
408
515
|
approvalMode,
|
|
409
516
|
closeDrawer,
|
|
517
|
+
defaultStartCwd,
|
|
410
518
|
defaultModelId,
|
|
411
519
|
defaultReasoningEffort,
|
|
412
520
|
saveAppSettings,
|
|
521
|
+
showToolCalls,
|
|
413
522
|
]);
|
|
414
523
|
|
|
415
524
|
const handleCancelOnboarding = useCallback(() => {
|
|
@@ -505,13 +614,16 @@ export default function App() {
|
|
|
505
614
|
ref={mainRef}
|
|
506
615
|
api={activeApi}
|
|
507
616
|
ws={activeWs}
|
|
617
|
+
bridgeUrl={bridgeUrl}
|
|
618
|
+
bridgeToken={bridgeToken}
|
|
508
619
|
onOpenDrawer={openDrawer}
|
|
509
620
|
onOpenGit={handleOpenChatGit}
|
|
510
621
|
defaultStartCwd={defaultStartCwd}
|
|
511
622
|
defaultModelId={defaultModelId}
|
|
512
623
|
defaultReasoningEffort={defaultReasoningEffort}
|
|
513
624
|
approvalMode={approvalMode}
|
|
514
|
-
|
|
625
|
+
showToolCalls={showToolCalls}
|
|
626
|
+
onDefaultStartCwdChange={handleDefaultStartCwdChange}
|
|
515
627
|
onChatContextChange={handleChatContextChange}
|
|
516
628
|
pendingOpenChatId={pendingMainChatId}
|
|
517
629
|
pendingOpenChatSnapshot={pendingMainChatSnapshot}
|
|
@@ -532,6 +644,8 @@ export default function App() {
|
|
|
532
644
|
onDefaultModelSettingsChange={handleDefaultModelSettingsChange}
|
|
533
645
|
approvalMode={approvalMode}
|
|
534
646
|
onApprovalModeChange={handleApprovalModeChange}
|
|
647
|
+
showToolCalls={showToolCalls}
|
|
648
|
+
onShowToolCallsChange={handleShowToolCallsChange}
|
|
535
649
|
onEditBridgeUrl={handleOpenBridgeUrlSettings}
|
|
536
650
|
onResetOnboarding={handleResetOnboarding}
|
|
537
651
|
onOpenDrawer={openDrawer}
|
|
@@ -559,13 +673,16 @@ export default function App() {
|
|
|
559
673
|
ref={mainRef}
|
|
560
674
|
api={activeApi}
|
|
561
675
|
ws={activeWs}
|
|
676
|
+
bridgeUrl={bridgeUrl}
|
|
677
|
+
bridgeToken={bridgeToken}
|
|
562
678
|
onOpenDrawer={openDrawer}
|
|
563
679
|
onOpenGit={handleOpenChatGit}
|
|
564
680
|
defaultStartCwd={defaultStartCwd}
|
|
565
681
|
defaultModelId={defaultModelId}
|
|
566
682
|
defaultReasoningEffort={defaultReasoningEffort}
|
|
567
683
|
approvalMode={approvalMode}
|
|
568
|
-
|
|
684
|
+
showToolCalls={showToolCalls}
|
|
685
|
+
onDefaultStartCwdChange={handleDefaultStartCwdChange}
|
|
569
686
|
onChatContextChange={handleChatContextChange}
|
|
570
687
|
pendingOpenChatId={pendingMainChatId}
|
|
571
688
|
pendingOpenChatSnapshot={pendingMainChatSnapshot}
|
|
@@ -582,9 +699,18 @@ export default function App() {
|
|
|
582
699
|
<SafeAreaProvider>
|
|
583
700
|
<View style={styles.root}>
|
|
584
701
|
{/* Main content */}
|
|
585
|
-
<View
|
|
702
|
+
<Animated.View
|
|
703
|
+
style={[
|
|
704
|
+
styles.screenFrame,
|
|
705
|
+
drawerOpen && styles.screenFrameOpen,
|
|
706
|
+
{
|
|
707
|
+
width: screenWidth,
|
|
708
|
+
transform: [{ translateX: contentTranslateX }, { scale: contentScale }],
|
|
709
|
+
},
|
|
710
|
+
]}
|
|
711
|
+
>
|
|
586
712
|
{renderScreen()}
|
|
587
|
-
</View>
|
|
713
|
+
</Animated.View>
|
|
588
714
|
|
|
589
715
|
{/* Overlay */}
|
|
590
716
|
<Animated.View
|
|
@@ -607,8 +733,6 @@ export default function App() {
|
|
|
607
733
|
api={activeApi}
|
|
608
734
|
ws={activeWs}
|
|
609
735
|
selectedChatId={selectedChatId}
|
|
610
|
-
selectedDefaultCwd={defaultStartCwd}
|
|
611
|
-
onSelectDefaultCwd={setDefaultStartCwd}
|
|
612
736
|
onSelectChat={handleSelectChat}
|
|
613
737
|
onNewChat={handleNewChat}
|
|
614
738
|
onNavigate={navigate}
|
|
@@ -637,17 +761,21 @@ function getAppSettingsPath(): string | null {
|
|
|
637
761
|
function parseAppSettings(raw: string): {
|
|
638
762
|
bridgeUrl: string | null;
|
|
639
763
|
bridgeToken: string | null;
|
|
764
|
+
defaultStartCwd: string | null;
|
|
640
765
|
defaultModelId: string | null;
|
|
641
766
|
defaultReasoningEffort: ReasoningEffort | null;
|
|
642
767
|
approvalMode: ApprovalMode;
|
|
768
|
+
showToolCalls: boolean;
|
|
643
769
|
} {
|
|
644
770
|
if (typeof raw !== 'string' || raw.trim().length === 0) {
|
|
645
771
|
return {
|
|
646
772
|
bridgeUrl: null,
|
|
647
773
|
bridgeToken: null,
|
|
774
|
+
defaultStartCwd: null,
|
|
648
775
|
defaultModelId: null,
|
|
649
776
|
defaultReasoningEffort: null,
|
|
650
777
|
approvalMode: 'normal',
|
|
778
|
+
showToolCalls: false,
|
|
651
779
|
};
|
|
652
780
|
}
|
|
653
781
|
|
|
@@ -664,15 +792,20 @@ function parseAppSettings(raw: string): {
|
|
|
664
792
|
return {
|
|
665
793
|
bridgeUrl: null,
|
|
666
794
|
bridgeToken: null,
|
|
795
|
+
defaultStartCwd: null,
|
|
667
796
|
defaultModelId: null,
|
|
668
797
|
defaultReasoningEffort: null,
|
|
669
798
|
approvalMode: 'normal',
|
|
799
|
+
showToolCalls: false,
|
|
670
800
|
};
|
|
671
801
|
}
|
|
672
802
|
|
|
673
803
|
return {
|
|
674
804
|
bridgeUrl: normalizeBridgeUrl((parsed as { bridgeUrl?: unknown }).bridgeUrl),
|
|
675
805
|
bridgeToken: normalizeBridgeToken((parsed as { bridgeToken?: unknown }).bridgeToken),
|
|
806
|
+
defaultStartCwd: normalizeDefaultStartCwd(
|
|
807
|
+
(parsed as { defaultStartCwd?: unknown }).defaultStartCwd
|
|
808
|
+
),
|
|
676
809
|
defaultModelId: normalizeModelId(
|
|
677
810
|
(parsed as { defaultModelId?: unknown }).defaultModelId
|
|
678
811
|
),
|
|
@@ -682,14 +815,19 @@ function parseAppSettings(raw: string): {
|
|
|
682
815
|
approvalMode: normalizeApprovalMode(
|
|
683
816
|
(parsed as { approvalMode?: unknown }).approvalMode
|
|
684
817
|
),
|
|
818
|
+
showToolCalls: normalizeBoolean(
|
|
819
|
+
(parsed as { showToolCalls?: unknown }).showToolCalls
|
|
820
|
+
),
|
|
685
821
|
};
|
|
686
822
|
} catch {
|
|
687
823
|
return {
|
|
688
824
|
bridgeUrl: null,
|
|
689
825
|
bridgeToken: null,
|
|
826
|
+
defaultStartCwd: null,
|
|
690
827
|
defaultModelId: null,
|
|
691
828
|
defaultReasoningEffort: null,
|
|
692
829
|
approvalMode: 'normal',
|
|
830
|
+
showToolCalls: false,
|
|
693
831
|
};
|
|
694
832
|
}
|
|
695
833
|
}
|
|
@@ -711,6 +849,15 @@ function normalizeBridgeToken(value: unknown): string | null {
|
|
|
711
849
|
return trimmed.length > 0 ? trimmed : null;
|
|
712
850
|
}
|
|
713
851
|
|
|
852
|
+
function normalizeDefaultStartCwd(value: unknown): string | null {
|
|
853
|
+
if (typeof value !== 'string') {
|
|
854
|
+
return null;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
const trimmed = value.trim();
|
|
858
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
859
|
+
}
|
|
860
|
+
|
|
714
861
|
function normalizeModelId(value: unknown): string | null {
|
|
715
862
|
if (typeof value !== 'string') {
|
|
716
863
|
return null;
|
|
@@ -744,6 +891,10 @@ function normalizeApprovalMode(value: unknown): ApprovalMode {
|
|
|
744
891
|
return value === 'yolo' ? 'yolo' : 'normal';
|
|
745
892
|
}
|
|
746
893
|
|
|
894
|
+
function normalizeBoolean(value: unknown): boolean {
|
|
895
|
+
return value === true;
|
|
896
|
+
}
|
|
897
|
+
|
|
747
898
|
const styles = StyleSheet.create({
|
|
748
899
|
root: {
|
|
749
900
|
flex: 1,
|
|
@@ -758,6 +909,16 @@ const styles = StyleSheet.create({
|
|
|
758
909
|
screen: {
|
|
759
910
|
flex: 1,
|
|
760
911
|
},
|
|
912
|
+
screenFrame: {
|
|
913
|
+
flex: 1,
|
|
914
|
+
backgroundColor: colors.bgMain,
|
|
915
|
+
},
|
|
916
|
+
screenFrameOpen: {
|
|
917
|
+
borderRadius: 28,
|
|
918
|
+
borderCurve: 'continuous',
|
|
919
|
+
overflow: 'hidden',
|
|
920
|
+
boxShadow: '0 22px 48px rgba(0, 0, 0, 0.34)',
|
|
921
|
+
},
|
|
761
922
|
overlay: {
|
|
762
923
|
...StyleSheet.absoluteFillObject,
|
|
763
924
|
backgroundColor: 'rgba(0,0,0,0.5)',
|
package/apps/mobile/app.json
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
"expo": {
|
|
3
3
|
"name": "Clawdex Mobile",
|
|
4
4
|
"slug": "clawdex-mobile",
|
|
5
|
-
"
|
|
5
|
+
"scheme": "clawdex",
|
|
6
|
+
"version": "3.0.0",
|
|
7
|
+
"userInterfaceStyle": "dark",
|
|
6
8
|
"orientation": "portrait",
|
|
7
9
|
"icon": "./assets/brand/app-icon.png",
|
|
8
10
|
"splash": {
|
|
@@ -12,15 +14,13 @@
|
|
|
12
14
|
},
|
|
13
15
|
"ios": {
|
|
14
16
|
"supportsTablet": true,
|
|
17
|
+
"appleTeamId": "4NWUS8362L",
|
|
15
18
|
"infoPlist": {
|
|
16
|
-
"NSCameraUsageDescription": "Clawdex uses the camera to scan bridge pairing QR codes.",
|
|
17
|
-
"NSMicrophoneUsageDescription": "Clawdex uses the microphone for voice-to-text input.",
|
|
18
19
|
"ITSAppUsesNonExemptEncryption": false
|
|
19
20
|
},
|
|
20
21
|
"bundleIdentifier": "com.mohitpatil973.clawdexmobile"
|
|
21
22
|
},
|
|
22
23
|
"android": {
|
|
23
|
-
"usesCleartextTraffic": true,
|
|
24
24
|
"adaptiveIcon": {
|
|
25
25
|
"foregroundImage": "./assets/brand/adaptive-icon.png",
|
|
26
26
|
"backgroundColor": "#000000"
|
|
@@ -28,9 +28,7 @@
|
|
|
28
28
|
"permissions": [
|
|
29
29
|
"android.permission.CAMERA",
|
|
30
30
|
"android.permission.RECORD_AUDIO",
|
|
31
|
-
"android.permission.MODIFY_AUDIO_SETTINGS"
|
|
32
|
-
"android.permission.FOREGROUND_SERVICE",
|
|
33
|
-
"android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"
|
|
31
|
+
"android.permission.MODIFY_AUDIO_SETTINGS"
|
|
34
32
|
],
|
|
35
33
|
"package": "com.mohitpatil973.clawdexmobile"
|
|
36
34
|
},
|
|
@@ -45,10 +43,30 @@
|
|
|
45
43
|
"experiments": {
|
|
46
44
|
"reactCompiler": true
|
|
47
45
|
},
|
|
48
|
-
"jsEngine": "hermes",
|
|
49
46
|
"plugins": [
|
|
50
47
|
"./plugins/withAndroidCleartextTraffic",
|
|
51
|
-
|
|
48
|
+
[
|
|
49
|
+
"expo-camera",
|
|
50
|
+
{
|
|
51
|
+
"cameraPermission": "Clawdex uses the camera to scan bridge pairing QR codes."
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
[
|
|
55
|
+
"expo-image-picker",
|
|
56
|
+
{
|
|
57
|
+
"photosPermission": "Clawdex uses your photo library so you can choose an image from your phone and attach it to a chat prompt or workflow sent to your own host bridge.",
|
|
58
|
+
"cameraPermission": "Clawdex uses the camera to scan bridge pairing QR codes.",
|
|
59
|
+
"microphonePermission": "Clawdex uses the microphone to record a short voice message that is transcribed into your chat input."
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
[
|
|
63
|
+
"expo-audio",
|
|
64
|
+
{
|
|
65
|
+
"microphonePermission": "Clawdex uses the microphone to record a short voice message that is transcribed into your chat input.",
|
|
66
|
+
"enableBackgroundPlayback": false,
|
|
67
|
+
"enableBackgroundRecording": false
|
|
68
|
+
}
|
|
69
|
+
]
|
|
52
70
|
],
|
|
53
71
|
"extra": {
|
|
54
72
|
"eas": {
|
package/apps/mobile/eas.json
CHANGED
|
@@ -8,23 +8,33 @@
|
|
|
8
8
|
"developmentClient": true,
|
|
9
9
|
"distribution": "internal",
|
|
10
10
|
"env": {
|
|
11
|
-
"EXPO_PUBLIC_ALLOW_QUERY_TOKEN_AUTH": "true"
|
|
11
|
+
"EXPO_PUBLIC_ALLOW_QUERY_TOKEN_AUTH": "true",
|
|
12
|
+
"EXPO_PUBLIC_PRIVACY_POLICY_URL": "https://mohit-patil.github.io/clawdex-mobile/privacy/",
|
|
13
|
+
"EXPO_PUBLIC_TERMS_OF_SERVICE_URL": "https://mohit-patil.github.io/clawdex-mobile/terms/"
|
|
12
14
|
}
|
|
13
15
|
},
|
|
14
16
|
"preview": {
|
|
15
17
|
"distribution": "internal",
|
|
16
18
|
"env": {
|
|
17
|
-
"EXPO_PUBLIC_ALLOW_QUERY_TOKEN_AUTH": "true"
|
|
19
|
+
"EXPO_PUBLIC_ALLOW_QUERY_TOKEN_AUTH": "true",
|
|
20
|
+
"EXPO_PUBLIC_PRIVACY_POLICY_URL": "https://mohit-patil.github.io/clawdex-mobile/privacy/",
|
|
21
|
+
"EXPO_PUBLIC_TERMS_OF_SERVICE_URL": "https://mohit-patil.github.io/clawdex-mobile/terms/"
|
|
18
22
|
}
|
|
19
23
|
},
|
|
20
24
|
"production": {
|
|
21
25
|
"autoIncrement": true,
|
|
22
26
|
"env": {
|
|
23
|
-
"EXPO_PUBLIC_ALLOW_QUERY_TOKEN_AUTH": "true"
|
|
27
|
+
"EXPO_PUBLIC_ALLOW_QUERY_TOKEN_AUTH": "true",
|
|
28
|
+
"EXPO_PUBLIC_PRIVACY_POLICY_URL": "https://mohit-patil.github.io/clawdex-mobile/privacy/",
|
|
29
|
+
"EXPO_PUBLIC_TERMS_OF_SERVICE_URL": "https://mohit-patil.github.io/clawdex-mobile/terms/"
|
|
24
30
|
}
|
|
25
31
|
}
|
|
26
32
|
},
|
|
27
33
|
"submit": {
|
|
28
|
-
"production": {
|
|
34
|
+
"production": {
|
|
35
|
+
"ios": {
|
|
36
|
+
"ascAppId": "6759833757"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
29
39
|
}
|
|
30
40
|
}
|
package/apps/mobile/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clawdex-mobile",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@expo/metro-runtime": "~55.0.6",
|
|
18
18
|
"@expo/vector-icons": "15.0.3",
|
|
19
|
-
"expo": "~55.0.
|
|
20
|
-
"expo-audio": "~55.0.
|
|
21
|
-
"expo-blur": "~55.0.
|
|
22
|
-
"expo-camera": "~55.0.
|
|
23
|
-
"expo-document-picker": "~55.0.
|
|
19
|
+
"expo": "~55.0.8",
|
|
20
|
+
"expo-audio": "~55.0.9",
|
|
21
|
+
"expo-blur": "~55.0.10",
|
|
22
|
+
"expo-camera": "~55.0.10",
|
|
23
|
+
"expo-document-picker": "~55.0.9",
|
|
24
24
|
"expo-file-system": "~55.0.9",
|
|
25
|
-
"expo-image-picker": "~55.0.
|
|
26
|
-
"expo-linear-gradient": "~55.0.
|
|
25
|
+
"expo-image-picker": "~55.0.13",
|
|
26
|
+
"expo-linear-gradient": "~55.0.9",
|
|
27
27
|
"react": "19.2.0",
|
|
28
28
|
"react-dom": "19.2.0",
|
|
29
29
|
"react-native": "0.83.2",
|
|
@@ -37,14 +37,14 @@
|
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/jest": "29.5.14",
|
|
40
|
-
"@types/node": "^22.
|
|
40
|
+
"@types/node": "^22.19.15",
|
|
41
41
|
"@types/react": "~19.2.10",
|
|
42
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
43
|
-
"@typescript-eslint/parser": "^8.
|
|
44
|
-
"eslint": "^10.0.
|
|
42
|
+
"@typescript-eslint/eslint-plugin": "^8.57.1",
|
|
43
|
+
"@typescript-eslint/parser": "^8.57.1",
|
|
44
|
+
"eslint": "^10.0.3",
|
|
45
45
|
"globals": "^16.5.0",
|
|
46
46
|
"jest": "^29.7.0",
|
|
47
|
-
"jest-expo": "~55.0.
|
|
47
|
+
"jest-expo": "~55.0.11",
|
|
48
48
|
"typescript": "~5.9.2"
|
|
49
49
|
},
|
|
50
50
|
"jest": {
|