Repository navigation
chore(sync): merge pingdotgg/t3code main #313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
6ed47b5
fix(server): route SQLite reads around writer contention (#23902)
Yash-Singh1 b7e802b
fix(claude): route approval feedback to the requesting agent (#23657)
Yash-Singh1 0c25c29
fix(web): align pull request file counts with diff stats (#23905)
Yash-Singh1 9b7e7df
fix(web): task durations over an hour no longer wrap in the tasks pan…
jamesvillarrubia 53245cc
fix(server): preserve Codex sign-in guidance in usage notices (#17055)
jieyuexing 7e52513
fix(server): restore Claude subscription usage through proxies (#12069)
Kanaliseren 71a283a
fix(server): Forgejo skipped jobs no longer keep a pull request watch…
Mnigos a68e6e9
fix(mobile): move Android undo toasts above bottom navigation (#23928)
PixPMusic 9a63802
perf(server): skip unused Git output line parsing (#23953)
juliusmarminge e64a6d4
fix(server): abort interrupted ACP MCP fetches (#23955)
juliusmarminge 56c365c
fix(web): new threads no longer hang when a project's machine is offl…
t3dotgg 6d9ec7b
fix(pi): stop blank input placeholders from failing the run (#23235)
only21mil 656f3f4
fix(cursor): fail turns that end in a transport error after commentar…
only21mil 49597c7
test(forgejo): answer the base branch read in the skipped-checks test…
juliusmarminge 807319c
fix(opencode): retry failed model catalogs until they recover (#23939)
Yash-Singh1 8931400
chore(sync): merge pingdotgg/t3code main
Yarden-zamir d7a8d6f
fix(server): avoid full shell read on resume (#23987)
Yash-Singh1 4042071
Merge remote-tracking branch 'origin/main' into fork-sync/2026-10-23-…
Yarden-zamir 7e7b780
chore(sync): merge pingdotgg/t3code main
Yarden-zamir File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
128 changes: 128 additions & 0 deletions
128
apps/mobile/src/features/home/ThreadUndoNotice.android.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| import { useLayoutEffect, useState } from "react"; | ||
| import { StyleSheet, View } from "react-native"; | ||
| import { GestureDetector, usePanGesture } from "react-native-gesture-handler"; | ||
| import Animated, { | ||
| cancelAnimation, | ||
| Easing, | ||
| FadeOut, | ||
| ReduceMotion, | ||
| runOnJS, | ||
| useAnimatedStyle, | ||
| useSharedValue, | ||
| withTiming, | ||
| type EntryAnimationsValues, | ||
| } from "react-native-reanimated"; | ||
| import { useSafeAreaInsets } from "react-native-safe-area-context"; | ||
| import { Toast } from "../../components/ui/Toast"; | ||
| import { MOBILE_MOTION } from "../../lib/designTokens"; | ||
| import { | ||
| dismissThreadUndoNotice, | ||
| readThreadUndoNotice, | ||
| useThreadUndoNotice, | ||
| } from "./thread-undo-notice"; | ||
|
|
||
| const SWIPE_TIMING = { duration: 160, reduceMotion: ReduceMotion.System }; | ||
| const ENTER_TIMING = { | ||
| duration: MOBILE_MOTION.enter, | ||
| easing: Easing.out(Easing.cubic), | ||
| reduceMotion: ReduceMotion.System, | ||
| }; | ||
| const NOTICE_EXITING = FadeOut.duration(MOBILE_MOTION.exit).reduceMotion(ReduceMotion.System); | ||
| const noticeEntering = (values: EntryAnimationsValues) => { | ||
| "worklet"; | ||
| return { | ||
| initialValues: { originY: values.targetOriginY + values.targetHeight + 12 }, | ||
| animations: { originY: withTiming(values.targetOriginY, ENTER_TIMING) }, | ||
| }; | ||
| }; | ||
|
|
||
| export function ThreadUndoNotice(props: { readonly visible: boolean }) { | ||
| const notice = useThreadUndoNotice(); | ||
| // Replacing a notice must also cancel the native gesture tracking the old one. | ||
| const [instance, setInstance] = useState({ notice, key: 0 }); | ||
| if (instance.notice !== notice) setInstance({ notice, key: instance.key + 1 }); | ||
| if (!props.visible || notice === null) return null; | ||
| return <SwipeableUndoNotice key={instance.key} notice={notice} />; | ||
| } | ||
|
|
||
| function SwipeableUndoNotice(props: { | ||
| readonly notice: NonNullable<ReturnType<typeof useThreadUndoNotice>>; | ||
| }) { | ||
| const { notice } = props; | ||
| const insets = useSafeAreaInsets(); | ||
| const translation = useSharedValue(0); | ||
| const width = useSharedValue(0); | ||
|
|
||
| useLayoutEffect( | ||
| () => () => { | ||
| cancelAnimation(translation); | ||
| }, | ||
| [translation], | ||
| ); | ||
|
|
||
| const dismiss = () => { | ||
| // A newer action can replace the notice while the swipe is animating out. | ||
| if (readThreadUndoNotice() === notice) dismissThreadUndoNotice(); | ||
| }; | ||
| const gesture = usePanGesture({ | ||
| activeOffsetX: [-10, 10], | ||
| failOffsetY: [-12, 12], | ||
| onUpdate: (event) => { | ||
| translation.set(event.translationX); | ||
| }, | ||
| onDeactivate: (event) => { | ||
| if ( | ||
| !event.canceled && | ||
| (Math.abs(event.translationX) > width.value * 0.25 || | ||
| (Math.abs(event.velocityX) > 800 && event.translationX * event.velocityX > 0)) | ||
| ) { | ||
| const direction = Math.sign(event.translationX || event.velocityX); | ||
| translation.set( | ||
| withTiming(direction * (width.value + 24), SWIPE_TIMING, (finished) => { | ||
| if (finished) runOnJS(dismiss)(); | ||
| }), | ||
| ); | ||
| } else { | ||
| translation.set(withTiming(0, SWIPE_TIMING)); | ||
| } | ||
| }, | ||
| }); | ||
| const animatedStyle = useAnimatedStyle(() => ({ | ||
| transform: [{ translateX: translation.value }], | ||
| })); | ||
|
|
||
| // Clip the entrance above navigation; the notice intentionally covers the anchored FAB. | ||
| return ( | ||
| <Animated.View | ||
| className="absolute inset-x-3 z-[100] overflow-hidden" | ||
| style={{ bottom: insets.bottom + 12 }} | ||
| pointerEvents="box-none" | ||
| exiting={NOTICE_EXITING} | ||
| onLayout={(event) => { | ||
| width.set(event.nativeEvent.layout.width); | ||
| }} | ||
| > | ||
| <GestureDetector gesture={gesture}> | ||
| <Animated.View collapsable={false} entering={noticeEntering} style={animatedStyle}> | ||
| {/* Keep the dismiss target separate so TalkBack can also focus Undo. */} | ||
| <View | ||
| accessible | ||
| accessibilityRole="alert" | ||
| accessibilityLiveRegion="assertive" | ||
| accessibilityLabel={`${notice.action} thread`} | ||
| accessibilityActions={[{ name: "dismiss", label: "Dismiss message" }]} | ||
| onAccessibilityAction={({ nativeEvent }) => { | ||
| if (nativeEvent.actionName === "dismiss") dismiss(); | ||
| }} | ||
| pointerEvents="none" | ||
| style={StyleSheet.absoluteFill} | ||
| /> | ||
| <Toast | ||
| message={`${notice.action} thread`} | ||
| action={{ label: "Undo", onPress: () => void notice.undo() }} | ||
| /> | ||
| </Animated.View> | ||
| </GestureDetector> | ||
| </Animated.View> | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Reach
tools/callbefore testing its cancellation.pendingFetchstalls the first request, which isinitialize. The fiber never receives a session or executessession.call, so this test passes without testing tool-call cancellation. Return handshake responses, then stalltools/calland assert that its signal is aborted.🤖 Prompt for AI Agents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 This file is the same as upstream pingdotgg/t3code main. Fork Sync merges upstream as is, so the fork does not change this test here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Yarden-zamir Understood. Keep the upstream test unchanged in this fork-sync PR. The coverage concern is an upstream follow-up, not a fork-specific change request.
Would you like me to open a GitHub issue to track that follow-up?
You are interacting with an AI system.