@10play/expo-air 0.6.0 → 0.7.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.
@@ -21,7 +21,10 @@ Pod::Spec.new do |s|
21
21
  s.dependency 'ExpoModulesCore'
22
22
  s.dependency 'React-RCTAppDelegate'
23
23
 
24
- s.resource = 'widget.jsbundle'
24
+ bundle_path = File.join(__dir__, 'widget.jsbundle')
25
+ if File.exist?(bundle_path)
26
+ s.resource = 'widget.jsbundle'
27
+ end
25
28
 
26
29
  # Swift/Objective-C compatibility
27
30
  s.pod_target_xcconfig = {
@@ -534,12 +534,13 @@ __d(function(g,r,i,a,m,e,d){'use strict';Object.defineProperty(e,'__esModule',{v
534
534
  __d(function(g,r,i,a,m,_e,d){"use strict";Object.defineProperty(_e,'__esModule',{value:!0}),Object.defineProperty(_e,"default",{enumerable:!0,get:function(){return c}});var e,t=r(d[0]),n=(e=t)&&e.__esModule?e:{default:e},u=(r(d[1]).default,!1),o=0;function f(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];u||(u=!0,0===e[0]&&(n.default.vibrate(400),e=e.slice(1)),0!==e.length?setTimeout(()=>l(++o,e,t,1),e[0]):u=!1)}function l(e,t,f,v){if(u&&e===o){if(n.default.vibrate(400),v>=t.length){if(!f)return void(u=!1);v=0}setTimeout(()=>l(e,t,f,v+1),t[v])}}var v={vibrate:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:400,t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(!u)if('number'==typeof e)n.default.vibrate(e);else{if(!Array.isArray(e))throw new Error('Vibration pattern should be a number or array');f(e,t)}},cancel:function(){u=!1}},c=v},482,[483,60]);
535
535
  __d(function(g,r,i,a,m,_e,d){"use strict";Object.defineProperty(_e,'__esModule',{value:!0}),Object.defineProperty(_e,"default",{enumerable:!0,get:function(){return n}});var e=r(d[0]);Object.keys(e).forEach(function(t){'default'===t||Object.prototype.hasOwnProperty.call(_e,t)||Object.defineProperty(_e,t,{enumerable:!0,get:function(){return e[t]}})});var t,n=((t=e)&&t.__esModule?t:{default:t}).default},483,[484]);
536
536
  __d(function(g,r,i,a,m,_e,_d){"use strict";Object.defineProperty(_e,'__esModule',{value:!0}),Object.defineProperty(_e,"default",{enumerable:!0,get:function(){return e}});var e=(function(e){if(e&&e.__esModule)return e;var t={};return e&&Object.keys(e).forEach(function(n){var u=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,u.get?u:{enumerable:!0,get:function(){return e[n]}})}),t.default=e,t})(r(_d[0])).getEnforcing('Vibration')},484,[50]);
537
- __d(function(g,r,i,a,m,_e,d){"use strict";function e(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(_e,'__esModule',{value:!0}),_e.BubbleContent=function(e){e.size,e.color;var h=e.expanded,b=void 0!==h&&h,C=e.serverUrl,O=void 0===C?"ws://localhost:3847":C,x=(0,s.useState)("disconnected"),y=(0,n.default)(x,2),E=y[0],I=y[1],_=(0,s.useState)([]),D=(0,n.default)(_,2),P=D[0],N=D[1],w=(0,s.useState)([]),k=(0,n.default)(w,2),U=k[0],j=k[1],L=(0,s.useState)("main"),B=(0,n.default)(L,2),V=B[0],G=B[1],M=(0,s.useState)([]),Y=(0,n.default)(M,2),W=Y[0],H=Y[1],Z=(0,s.useState)(!1),z=(0,n.default)(Z,2),q=z[0],F=z[1],X=(0,s.useState)(),K=(0,n.default)(X,2),J=K[0],Q=K[1],$=(0,s.useState)("chat"),ee=(0,n.default)($,2),te=ee[0],ne=ee[1],ae=(0,s.useRef)(!1),re=(0,s.useRef)(0),se=(0,s.useRef)([]),oe=(0,s.useRef)(null),ie=(0,s.useRef)(null);(0,s.useEffect)(()=>{b&&"chat"===te&&setTimeout(()=>ie.current?.focus(),100)},[b]);var ce=J?.match(/\/pull\/(\d+)/)?.[1];(0,s.useEffect)(()=>{console.log("[expo-air] Connecting to:",O);var e=(0,p.createWebSocketClient)({url:O,onStatusChange:I,onMessage:le,onError:e=>{console.error("[expo-air] WebSocket error:",e)}});return e.connect(),()=>{e.disconnect()}},[O]),(0,s.useEffect)(()=>(0,S.setupTapHandler)((e,t)=>{var n=(0,p.getWebSocketClient)();n&&!n.isConnected()&&n.connect()}),[]);var ue=(0,s.useCallback)((e,t)=>{var n=se.current;if(n.length>0){var s={type:"assistant_parts",promptId:e,parts:n,isComplete:t,timestamp:Date.now()};N(e=>[...e,s])}se.current=[],oe.current=null,j([])},[]),le=(0,s.useCallback)(e=>{switch(e.type){case"stream":if(e.promptId!==oe.current&&(se.current.length>0&&oe.current&&ue(oe.current,!1),oe.current=e.promptId),!e.done&&e.chunk){var t=se.current,n=t[t.length-1];"text"===n?.type?(n.content+=e.chunk,se.current=[...t]):se.current=[...t,{type:"text",id:"text-"+re.current++,content:e.chunk}],j([...se.current])}break;case"tool":if("started"!==e.status){var s={type:"tool",id:"tool-"+re.current++,toolName:e.toolName,status:e.status,input:e.input,output:e.output,timestamp:e.timestamp};se.current=[...se.current,s],j([...se.current])}break;case"result":if(se.current.length>0){var o={type:"assistant_parts",promptId:e.promptId,parts:se.current,isComplete:!0,timestamp:e.timestamp};if(void 0!==e.costUsd||void 0!==e.durationMs||!e.success&&e.error){var c={...e,result:void 0};N(e=>[...e,o,c])}else N(e=>[...e,o])}else(void 0!==e.costUsd||void 0!==e.durationMs||!e.success&&e.error)&&N(t=>[...t,e]);se.current=[],oe.current=null,j([]);break;case"error":if(se.current.length>0&&oe.current){var u={type:"assistant_parts",promptId:oe.current,parts:se.current,isComplete:!1,timestamp:Date.now()};N(t=>[...t,u,e])}else N(t=>[...t,e]);se.current=[],oe.current=null,j([]);break;case"status":break;case"session_cleared":N([]),se.current=[],oe.current=null,re.current=0,j([]);break;case"stopped":se.current.length>0&&oe.current?ue(oe.current,!1):(se.current=[],oe.current=null,j([]));break;case"history":var l=e.entries.flatMap(e=>"user"===e.role?[{type:"user_prompt",content:e.content,timestamp:e.timestamp}]:"assistant"===e.role?[{type:"history_result",content:e.content,timestamp:e.timestamp}]:"tool"===e.role?[{type:"tool",promptId:"",toolName:e.toolName,status:e.status,input:e.input,output:e.output,timestamp:e.timestamp}]:"system"===e.role?[{type:"system_message",messageType:e.type,content:e.content,timestamp:e.timestamp}]:[]);N(l);break;case"git_status":G(e.branchName),H(e.changes),F(e.hasPR),Q(e.prUrl)}},[ue]),de=(0,s.useCallback)((function(){var e=(0,t.default)(function*(e){if(!ae.current){var t=yield(0,S.requestPushToken)();if(t){var n=(0,p.getWebSocketClient)();n?.isConnected()&&(n.sendPushToken(t),ae.current=!0)}}N(t=>[...t,{type:"user_prompt",content:e,timestamp:Date.now()}]),se.current=[],oe.current=null,j([]);var s=(0,p.getWebSocketClient)();s&&s.sendPrompt(e)});return function(t){return e.apply(this,arguments)}})(),[]),pe=(0,s.useCallback)(()=>{var e=(0,p.getWebSocketClient)();e&&e.requestNewSession()},[]),me=(0,s.useCallback)(()=>{var e=(0,p.getWebSocketClient)();e&&e.requestStop()},[]),Se=(0,s.useCallback)(()=>{ne("chat"),de("Look at my current git changes and create a commit with a good conventional commit message. Stage all changes and commit them.")},[de]),he=(0,s.useCallback)(()=>{ne("chat"),de("Create a pull request for my current branch. First commit any uncommitted changes with a good message. Then generate a title and description based on the commits, and use `gh pr create --title \"...\" --body \"...\"` (non-interactive mode) to create it. Push to remote first if needed.")},[de]),Te=(0,s.useCallback)(()=>{J&&o.Linking.openURL(J)},[J]),ge=(0,s.useCallback)(()=>{var e=(0,p.getWebSocketClient)();e&&e.requestDiscardChanges()},[]);if(!b)return(0,T.jsx)(o.View,{style:v.collapsedPill,children:(0,T.jsx)(A,{status:E})});return(0,T.jsxs)(o.View,{style:v.expanded,children:[(0,T.jsx)(f,{status:E,branchName:V}),(0,T.jsx)(R,{activeTab:te,onTabChange:ne,onNewSession:pe,canStartNew:"connected"===E,hasPR:q,hasChanges:W.length>0,prNumber:ce,onCreatePR:he,onCommit:Se,onViewPR:Te}),(0,T.jsx)(o.View,{style:v.body,children:"chat"===te?(0,T.jsx)(u.ResponseArea,{messages:P,currentParts:U}):(0,T.jsx)(l.GitChangesTab,{changes:W,onDiscard:ge})}),"chat"===te&&(0,T.jsx)(c.PromptInput,{ref:ie,onSubmit:de,onStop:me,disabled:"disconnected"===E,isProcessing:"processing"===E})]})};var t=e(r(d[0])),n=e(r(d[1])),s=r(d[2]),o=r(d[3]),c=r(d[4]),u=r(d[5]),l=r(d[6]),p=r(d[7]),S=r(d[8]),h=r(d[9]),T=r(d[10]),b=o.NativeModules.WidgetBridge,C=o.NativeModules.ExpoAir;function O(){try{b?.collapse?b.collapse():C?.collapse?C.collapse():console.warn("[expo-air] No collapse method available")}catch(e){console.warn("[expo-air] Failed to collapse:",e)}}function f(e){var t=e.status,n=e.branchName,s={disconnected:h.COLORS.STATUS_ERROR,connecting:h.COLORS.STATUS_INFO,connected:h.COLORS.STATUS_SUCCESS,processing:h.COLORS.STATUS_INFO};return(0,T.jsxs)(o.View,{style:v.header,children:[(0,T.jsx)(o.TouchableOpacity,{onPress:O,style:v.closeButton,children:(0,T.jsx)(o.Text,{style:v.closeButtonText,children:"\u2715"})}),(0,T.jsx)(o.Text,{style:v.branchName,numberOfLines:1,children:n}),(0,T.jsx)(o.View,{style:[v.statusDot,{backgroundColor:s[t]}]})]})}function R(e){var t=e.activeTab,n=e.onTabChange,s=e.onNewSession,c=e.canStartNew,u=e.hasPR,l=e.hasChanges,p=e.prNumber,S=e.onCreatePR,h=e.onCommit,b=e.onViewPR;return(0,T.jsxs)(o.View,{style:v.tabBar,children:[(0,T.jsxs)(o.View,{style:v.tabButtons,children:[(0,T.jsx)(o.TouchableOpacity,{onPress:()=>n("chat"),children:(0,T.jsx)(o.Text,{style:[v.tabText,"chat"===t?v.tabTextActive:v.tabTextInactive],children:"Chat"})}),(0,T.jsx)(o.TouchableOpacity,{onPress:()=>n("changes"),children:(0,T.jsx)(o.Text,{style:[v.tabText,"changes"===t?v.tabTextActive:v.tabTextInactive],children:"Changes"})})]}),"chat"===t?(0,T.jsx)(o.TouchableOpacity,{onPress:s,style:[v.ctaButton,!c&&v.ctaButtonDisabled],disabled:!c,children:(0,T.jsx)(o.Text,{style:[v.ctaText,!c&&v.ctaTextDisabled],children:"New"})}):!u&&l?(0,T.jsx)(x,{onPress:S,children:"Create PR"}):u&&l?(0,T.jsx)(x,{onPress:h,children:"Commit"}):u&&!l&&p?(0,T.jsxs)(x,{onPress:b,children:["#",p]}):null]})}function x(e){var t=e.children,n=e.onPress,c=(0,s.useRef)(new o.Animated.Value(.6)).current;return(0,s.useEffect)(()=>{var e=o.Animated.loop(o.Animated.sequence([o.Animated.timing(c,{toValue:.9,duration:1500,easing:o.Easing.inOut(o.Easing.ease),useNativeDriver:!0}),o.Animated.timing(c,{toValue:.6,duration:1500,easing:o.Easing.inOut(o.Easing.ease),useNativeDriver:!0})]));return e.start(),()=>e.stop()},[c]),(0,T.jsx)(o.TouchableOpacity,{onPress:n,style:v.ctaButton,activeOpacity:.7,children:(0,T.jsx)(o.Animated.Text,{style:[v.ctaText,{opacity:c}],children:t})})}function A(e){var t=e.status,n={disconnected:h.COLORS.STATUS_ERROR,connecting:h.COLORS.STATUS_INFO,connected:h.COLORS.STATUS_SUCCESS,processing:h.COLORS.STATUS_INFO},c="processing"===t||"connecting"===t,u=(0,s.useRef)(new o.Animated.Value(1)).current,l=(0,s.useRef)(new o.Animated.Value(.4)).current;return(0,s.useEffect)(()=>{if(c){var e=o.Animated.loop(o.Animated.sequence([o.Animated.parallel([o.Animated.timing(u,{toValue:1.3,duration:1200,easing:o.Easing.inOut(o.Easing.ease),useNativeDriver:!0}),o.Animated.timing(l,{toValue:0,duration:1200,easing:o.Easing.inOut(o.Easing.ease),useNativeDriver:!0})]),o.Animated.parallel([o.Animated.timing(u,{toValue:1,duration:0,useNativeDriver:!0}),o.Animated.timing(l,{toValue:.4,duration:0,useNativeDriver:!0})])]));return e.start(),()=>e.stop()}u.setValue(1),l.setValue(.4)},[c,u,l]),(0,T.jsxs)(o.View,{style:v.indicatorContainer,children:[(0,T.jsx)(o.View,{style:[v.indicator,{backgroundColor:n[t]}]}),c&&(0,T.jsx)(o.Animated.View,{style:[v.indicatorRing,{borderColor:n[t],transform:[{scale:u}],opacity:l}]})]})}var v=o.StyleSheet.create({collapsedPill:{width:100,height:32,backgroundColor:"transparent",alignItems:"center",justifyContent:"center"},indicatorContainer:{width:20,height:20,alignItems:"center",justifyContent:"center"},indicator:{width:h.SIZES.STATUS_DOT,height:h.SIZES.STATUS_DOT,borderRadius:h.SIZES.STATUS_DOT/2},indicatorRing:{position:"absolute",width:16,height:16,borderRadius:8,borderWidth:1.5,opacity:.4},expanded:{flex:1,backgroundColor:h.COLORS.BACKGROUND,borderRadius:h.LAYOUT.BORDER_RADIUS_LG,overflow:"hidden"},header:{flexDirection:"row",alignItems:"center",paddingHorizontal:h.LAYOUT.CONTENT_PADDING_H,paddingVertical:h.SPACING.MD+2,borderBottomWidth:1,borderBottomColor:h.COLORS.BORDER},closeButton:{width:h.SIZES.CLOSE_BUTTON,height:h.SIZES.CLOSE_BUTTON,borderRadius:h.SIZES.CLOSE_BUTTON/2,backgroundColor:"transparent",alignItems:"center",justifyContent:"center",marginRight:h.SPACING.MD},closeButtonText:{color:"transparent",fontSize:h.TYPOGRAPHY.SIZE_MD,fontWeight:h.TYPOGRAPHY.WEIGHT_SEMIBOLD},branchName:{flex:1,color:h.COLORS.TEXT_SECONDARY,fontSize:h.TYPOGRAPHY.SIZE_MD,fontWeight:h.TYPOGRAPHY.WEIGHT_MEDIUM},statusDot:{width:h.SIZES.STATUS_DOT,height:h.SIZES.STATUS_DOT,borderRadius:h.SIZES.STATUS_DOT/2,marginLeft:h.SPACING.MD},ctaButton:{paddingHorizontal:h.SIZES.CTA_PADDING_H,paddingVertical:h.SIZES.CTA_PADDING_V,borderRadius:h.LAYOUT.BORDER_RADIUS_SM,backgroundColor:h.COLORS.BACKGROUND_INTERACTIVE},ctaButtonDisabled:{opacity:.4},ctaText:{color:h.COLORS.TEXT_PRIMARY,fontSize:h.TYPOGRAPHY.SIZE_SM,fontWeight:h.TYPOGRAPHY.WEIGHT_SEMIBOLD},ctaTextDisabled:{opacity:.6},tabBar:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingHorizontal:h.LAYOUT.CONTENT_PADDING_H,paddingVertical:h.SPACING.SM+2,borderBottomWidth:1,borderBottomColor:h.COLORS.BORDER},tabButtons:{flexDirection:"row",gap:h.SPACING.XL},tabText:{fontSize:h.TYPOGRAPHY.SIZE_LG,fontWeight:h.TYPOGRAPHY.WEIGHT_MEDIUM},tabTextActive:{color:h.COLORS.TEXT_PRIMARY},tabTextInactive:{color:h.COLORS.TEXT_MUTED},body:{flex:1,backgroundColor:h.COLORS.BACKGROUND_ELEVATED}})},485,[346,29,63,258,486,488,489,490,491,487,250]);
537
+ __d(function(g,r,i,a,m,_e,d){"use strict";function e(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(_e,'__esModule',{value:!0}),_e.BubbleContent=function(e){e.size,e.color;var T=e.expanded,C=void 0!==T&&T,O=e.serverUrl,f=void 0===O?"ws://localhost:3847":O,A=(0,s.useState)("disconnected"),E=(0,n.default)(A,2),_=E[0],I=E[1],P=(0,s.useState)([]),D=(0,n.default)(P,2),N=D[0],k=D[1],w=(0,s.useState)([]),B=(0,n.default)(w,2),j=B[0],L=B[1],U=(0,s.useState)("main"),G=(0,n.default)(U,2),V=G[0],M=G[1],Y=(0,s.useState)([]),W=(0,n.default)(Y,2),H=W[0],Z=W[1],q=(0,s.useState)(!1),z=(0,n.default)(q,2),X=z[0],F=z[1],K=(0,s.useState)(),J=(0,n.default)(K,2),Q=J[0],$=J[1],ee=(0,s.useState)("chat"),te=(0,n.default)(ee,2),ne=te[0],ae=te[1],re=(0,s.useState)(!1),se=(0,n.default)(re,2),oe=se[0],ie=se[1],ce=(0,s.useState)([]),le=(0,n.default)(ce,2),ue=le[0],de=le[1],he=(0,s.useState)(null),Se=(0,n.default)(he,2),pe=Se[0],me=Se[1],Te=(0,s.useRef)(!1),be=(0,s.useRef)(0),ge=(0,s.useRef)([]),Ce=(0,s.useRef)(null),Oe=(0,s.useRef)(null);(0,s.useEffect)(()=>{C&&"chat"===ne&&setTimeout(()=>Oe.current?.focus(),100)},[C]);var fe=Q?.match(/\/pull\/(\d+)/)?.[1];(0,s.useEffect)(()=>{console.log("[expo-air] Connecting to:",f);var e=(0,h.createWebSocketClient)({url:f,onStatusChange:I,onMessage:xe,onError:e=>{console.error("[expo-air] WebSocket error:",e)}});return e.connect(),()=>{e.disconnect()}},[f]),(0,s.useEffect)(()=>(0,S.setupTapHandler)((e,t)=>{var n=(0,h.getWebSocketClient)();n&&!n.isConnected()&&n.connect()}),[]);var Re=(0,s.useCallback)((e,t)=>{var n=ge.current;if(n.length>0){var s={type:"assistant_parts",promptId:e,parts:n,isComplete:t,timestamp:Date.now()};k(e=>[...e,s])}ge.current=[],Ce.current=null,L([])},[]),xe=(0,s.useCallback)(e=>{switch(e.type){case"stream":if(e.promptId!==Ce.current&&(ge.current.length>0&&Ce.current&&Re(Ce.current,!1),Ce.current=e.promptId),!e.done&&e.chunk){var t=ge.current,n=t[t.length-1];"text"===n?.type?(n.content+=e.chunk,ge.current=[...t]):ge.current=[...t,{type:"text",id:"text-"+be.current++,content:e.chunk}],L([...ge.current])}break;case"tool":if("started"!==e.status){var s={type:"tool",id:"tool-"+be.current++,toolName:e.toolName,status:e.status,input:e.input,output:e.output,timestamp:e.timestamp};ge.current=[...ge.current,s],L([...ge.current])}break;case"result":if(ge.current.length>0){var o={type:"assistant_parts",promptId:e.promptId,parts:ge.current,isComplete:!0,timestamp:e.timestamp};if(void 0!==e.costUsd||void 0!==e.durationMs||!e.success&&e.error){var c={...e,result:void 0};k(e=>[...e,o,c])}else k(e=>[...e,o])}else(void 0!==e.costUsd||void 0!==e.durationMs||!e.success&&e.error)&&k(t=>[...t,e]);ge.current=[],Ce.current=null,L([]);break;case"error":if(ge.current.length>0&&Ce.current){var l={type:"assistant_parts",promptId:Ce.current,parts:ge.current,isComplete:!1,timestamp:Date.now()};k(t=>[...t,l,e])}else k(t=>[...t,e]);ge.current=[],Ce.current=null,L([]);break;case"status":break;case"session_cleared":k([]),ge.current=[],Ce.current=null,be.current=0,L([]);break;case"stopped":ge.current.length>0&&Ce.current?Re(Ce.current,!1):(ge.current=[],Ce.current=null,L([]));break;case"history":var u=e.entries.flatMap(e=>"user"===e.role?[{type:"user_prompt",content:e.content,timestamp:e.timestamp}]:"assistant"===e.role?[{type:"history_result",content:e.content,timestamp:e.timestamp}]:"tool"===e.role?[{type:"tool",promptId:"",toolName:e.toolName,status:e.status,input:e.input,output:e.output,timestamp:e.timestamp}]:"system"===e.role?[{type:"system_message",messageType:e.type,content:e.content,timestamp:e.timestamp}]:[]);k(u);break;case"git_status":M(e.branchName),Z(e.changes),F(e.hasPR),$(e.prUrl);break;case"branches_list":de(e.branches);break;case"branch_switched":case"branch_created":e.success?(ie(!1),me(null)):e.error&&me(e.error)}},[Re]),Ae=(0,s.useCallback)((function(){var e=(0,t.default)(function*(e){if(!Te.current){var t=yield(0,S.requestPushToken)();if(t){var n=(0,h.getWebSocketClient)();n?.isConnected()&&(n.sendPushToken(t),Te.current=!0)}}k(t=>[...t,{type:"user_prompt",content:e,timestamp:Date.now()}]),ge.current=[],Ce.current=null,L([]);var s=(0,h.getWebSocketClient)();s&&s.sendPrompt(e)});return function(t){return e.apply(this,arguments)}})(),[]),ve=(0,s.useCallback)(()=>{var e=(0,h.getWebSocketClient)();e&&e.requestNewSession()},[]),ye=(0,s.useCallback)(()=>{var e=(0,h.getWebSocketClient)();e&&e.requestStop()},[]),Ee=(0,s.useCallback)(()=>{ae("chat"),Ae("Look at my current git changes and create a commit with a good conventional commit message. Stage all changes and commit them.")},[Ae]),Ie=(0,s.useCallback)(()=>{ae("chat"),Ae("Create a pull request for my current branch. First commit any uncommitted changes with a good message. Then generate a title and description based on the commits, and use `gh pr create --title \"...\" --body \"...\"` (non-interactive mode) to create it. Push to remote first if needed.")},[Ae]),Pe=(0,s.useCallback)(()=>{Q&&o.Linking.openURL(Q)},[Q]),De=(0,s.useCallback)(()=>{var e=(0,h.getWebSocketClient)();e&&e.requestDiscardChanges()},[]),Ne=(0,s.useCallback)(()=>{if(ie(e=>!e),!oe){var e=(0,h.getWebSocketClient)();e&&e.requestBranches()}},[oe]),ke=(0,s.useCallback)(e=>{me(null);var t=(0,h.getWebSocketClient)();t&&t.requestSwitchBranch(e)},[]),we=(0,s.useCallback)(e=>{me(null);var t=(0,h.getWebSocketClient)();t&&t.requestCreateBranch(e)},[]);if(!C)return(0,b.jsx)(o.View,{style:y.collapsedPill,children:(0,b.jsx)(v,{status:_})});return(0,b.jsxs)(o.View,{style:y.expanded,children:[(0,b.jsx)(R,{status:_,branchName:V,onBranchPress:Ne}),(0,b.jsx)(x,{activeTab:ne,onTabChange:ae,onNewSession:ve,canStartNew:"connected"===_,hasPR:X,hasChanges:H.length>0,prNumber:fe,onCreatePR:Ie,onCommit:Ee,onViewPR:Pe}),(0,b.jsx)(o.View,{style:y.body,children:"chat"===ne?(0,b.jsx)(l.ResponseArea,{messages:N,currentParts:j}):(0,b.jsx)(u.GitChangesTab,{changes:H,onDiscard:De})}),"chat"===ne&&(0,b.jsx)(c.PromptInput,{ref:Oe,onSubmit:Ae,onStop:ye,disabled:"disconnected"===_,isProcessing:"processing"===_}),oe&&(0,b.jsx)(p.BranchSwitcher,{branches:ue,currentBranch:V,onSelect:ke,onCreate:we,onClose:()=>{ie(!1),me(null)},error:pe})]})};var t=e(r(d[0])),n=e(r(d[1])),s=r(d[2]),o=r(d[3]),c=r(d[4]),l=r(d[5]),u=r(d[6]),h=r(d[7]),S=r(d[8]),p=r(d[9]),T=r(d[10]),b=r(d[11]),C=o.NativeModules.WidgetBridge,O=o.NativeModules.ExpoAir;function f(){try{C?.collapse?C.collapse():O?.collapse?O.collapse():console.warn("[expo-air] No collapse method available")}catch(e){console.warn("[expo-air] Failed to collapse:",e)}}function R(e){var t=e.status,n=e.branchName,s=e.onBranchPress,c={disconnected:T.COLORS.STATUS_ERROR,connecting:T.COLORS.STATUS_INFO,connected:T.COLORS.STATUS_SUCCESS,processing:T.COLORS.STATUS_INFO};return(0,b.jsxs)(o.View,{style:y.header,children:[(0,b.jsx)(o.TouchableOpacity,{onPress:f,style:y.closeButton,children:(0,b.jsx)(o.Text,{style:y.closeButtonText,children:"\u2715"})}),(0,b.jsxs)(o.TouchableOpacity,{style:y.branchButton,onPress:s,children:[(0,b.jsx)(o.Text,{style:y.branchName,numberOfLines:1,children:n}),(0,b.jsx)(o.Text,{style:y.branchChevron,children:"\u25be"})]}),(0,b.jsx)(o.View,{style:[y.statusDot,{backgroundColor:c[t]}]})]})}function x(e){var t=e.activeTab,n=e.onTabChange,s=e.onNewSession,c=e.canStartNew,l=e.hasPR,u=e.hasChanges,h=e.prNumber,S=e.onCreatePR,p=e.onCommit,T=e.onViewPR;return(0,b.jsxs)(o.View,{style:y.tabBar,children:[(0,b.jsxs)(o.View,{style:y.tabButtons,children:[(0,b.jsx)(o.TouchableOpacity,{onPress:()=>n("chat"),children:(0,b.jsx)(o.Text,{style:[y.tabText,"chat"===t?y.tabTextActive:y.tabTextInactive],children:"Chat"})}),(0,b.jsx)(o.TouchableOpacity,{onPress:()=>n("changes"),children:(0,b.jsx)(o.Text,{style:[y.tabText,"changes"===t?y.tabTextActive:y.tabTextInactive],children:"Changes"})})]}),"chat"===t?(0,b.jsx)(o.TouchableOpacity,{onPress:s,style:[y.ctaButton,!c&&y.ctaButtonDisabled],disabled:!c,children:(0,b.jsx)(o.Text,{style:[y.ctaText,!c&&y.ctaTextDisabled],children:"New"})}):!l&&u?(0,b.jsx)(A,{onPress:S,children:"Create PR"}):l&&u?(0,b.jsx)(A,{onPress:p,children:"Commit"}):l&&!u&&h?(0,b.jsxs)(A,{onPress:T,children:["#",h]}):null]})}function A(e){var t=e.children,n=e.onPress,c=(0,s.useRef)(new o.Animated.Value(.6)).current;return(0,s.useEffect)(()=>{var e=o.Animated.loop(o.Animated.sequence([o.Animated.timing(c,{toValue:.9,duration:1500,easing:o.Easing.inOut(o.Easing.ease),useNativeDriver:!0}),o.Animated.timing(c,{toValue:.6,duration:1500,easing:o.Easing.inOut(o.Easing.ease),useNativeDriver:!0})]));return e.start(),()=>e.stop()},[c]),(0,b.jsx)(o.TouchableOpacity,{onPress:n,style:y.ctaButton,activeOpacity:.7,children:(0,b.jsx)(o.Animated.Text,{style:[y.ctaText,{opacity:c}],children:t})})}function v(e){var t=e.status,n={disconnected:T.COLORS.STATUS_ERROR,connecting:T.COLORS.STATUS_INFO,connected:T.COLORS.STATUS_SUCCESS,processing:T.COLORS.STATUS_INFO},c="processing"===t||"connecting"===t,l=(0,s.useRef)(new o.Animated.Value(1)).current,u=(0,s.useRef)(new o.Animated.Value(.4)).current;return(0,s.useEffect)(()=>{if(c){var e=o.Animated.loop(o.Animated.sequence([o.Animated.parallel([o.Animated.timing(l,{toValue:1.3,duration:1200,easing:o.Easing.inOut(o.Easing.ease),useNativeDriver:!0}),o.Animated.timing(u,{toValue:0,duration:1200,easing:o.Easing.inOut(o.Easing.ease),useNativeDriver:!0})]),o.Animated.parallel([o.Animated.timing(l,{toValue:1,duration:0,useNativeDriver:!0}),o.Animated.timing(u,{toValue:.4,duration:0,useNativeDriver:!0})])]));return e.start(),()=>e.stop()}l.setValue(1),u.setValue(.4)},[c,l,u]),(0,b.jsxs)(o.View,{style:y.indicatorContainer,children:[(0,b.jsx)(o.View,{style:[y.indicator,{backgroundColor:n[t]}]}),c&&(0,b.jsx)(o.Animated.View,{style:[y.indicatorRing,{borderColor:n[t],transform:[{scale:l}],opacity:u}]})]})}var y=o.StyleSheet.create({collapsedPill:{width:100,height:32,backgroundColor:"transparent",alignItems:"center",justifyContent:"center"},indicatorContainer:{width:20,height:20,alignItems:"center",justifyContent:"center"},indicator:{width:T.SIZES.STATUS_DOT,height:T.SIZES.STATUS_DOT,borderRadius:T.SIZES.STATUS_DOT/2},indicatorRing:{position:"absolute",width:16,height:16,borderRadius:8,borderWidth:1.5,opacity:.4},expanded:{flex:1,backgroundColor:T.COLORS.BACKGROUND,borderRadius:T.LAYOUT.BORDER_RADIUS_LG,overflow:"hidden"},header:{flexDirection:"row",alignItems:"center",paddingHorizontal:T.LAYOUT.CONTENT_PADDING_H,paddingVertical:T.SPACING.MD+2,borderBottomWidth:1,borderBottomColor:T.COLORS.BORDER},closeButton:{width:T.SIZES.CLOSE_BUTTON,height:T.SIZES.CLOSE_BUTTON,borderRadius:T.SIZES.CLOSE_BUTTON/2,backgroundColor:"transparent",alignItems:"center",justifyContent:"center",marginRight:T.SPACING.MD},closeButtonText:{color:"transparent",fontSize:T.TYPOGRAPHY.SIZE_MD,fontWeight:T.TYPOGRAPHY.WEIGHT_SEMIBOLD},branchButton:{flex:1,flexDirection:"row",alignItems:"center"},branchName:{flexShrink:1,color:T.COLORS.TEXT_SECONDARY,fontSize:T.TYPOGRAPHY.SIZE_MD,fontWeight:T.TYPOGRAPHY.WEIGHT_MEDIUM},branchChevron:{color:T.COLORS.TEXT_MUTED,fontSize:T.TYPOGRAPHY.SIZE_SM,marginLeft:T.SPACING.XS},statusDot:{width:T.SIZES.STATUS_DOT,height:T.SIZES.STATUS_DOT,borderRadius:T.SIZES.STATUS_DOT/2,marginLeft:T.SPACING.MD},ctaButton:{paddingHorizontal:T.SIZES.CTA_PADDING_H,paddingVertical:T.SIZES.CTA_PADDING_V,borderRadius:T.LAYOUT.BORDER_RADIUS_SM,backgroundColor:T.COLORS.BACKGROUND_INTERACTIVE},ctaButtonDisabled:{opacity:.4},ctaText:{color:T.COLORS.TEXT_PRIMARY,fontSize:T.TYPOGRAPHY.SIZE_SM,fontWeight:T.TYPOGRAPHY.WEIGHT_SEMIBOLD},ctaTextDisabled:{opacity:.6},tabBar:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingHorizontal:T.LAYOUT.CONTENT_PADDING_H,paddingVertical:T.SPACING.SM+2,borderBottomWidth:1,borderBottomColor:T.COLORS.BORDER},tabButtons:{flexDirection:"row",gap:T.SPACING.XL},tabText:{fontSize:T.TYPOGRAPHY.SIZE_LG,fontWeight:T.TYPOGRAPHY.WEIGHT_MEDIUM},tabTextActive:{color:T.COLORS.TEXT_PRIMARY},tabTextInactive:{color:T.COLORS.TEXT_MUTED},body:{flex:1,backgroundColor:T.COLORS.BACKGROUND_ELEVATED}})},485,[346,29,63,258,486,488,489,490,491,492,487,250]);
538
538
  __d(function(g,r,i,a,m,_e,d){"use strict";Object.defineProperty(_e,'__esModule',{value:!0}),Object.defineProperty(_e,"PromptInput",{enumerable:!0,get:function(){return c}});var e,t=r(d[0]),o=(e=t)&&e.__esModule?e:{default:e},n=r(d[1]),s=r(d[2]),l=r(d[3]),u=r(d[4]),c=(0,n.forwardRef)((e,t)=>{var c=e.onSubmit,R=e.onStop,h=e.disabled,S=void 0!==h&&h,C=e.isProcessing,p=void 0!==C&&C,I=(0,n.useState)(""),f=(0,o.default)(I,2),y=f[0],B=f[1],_=(0,n.useRef)(null);(0,n.useImperativeHandle)(t,()=>({focus:()=>_.current?.focus()}));var L=()=>{var e=y.trim();!e||S||p||(c(e),B(""))},w=y.trim().length>0&&!S&&!p;return(0,u.jsxs)(s.View,{style:O.container,children:[(0,u.jsx)(s.TextInput,{ref:_,style:O.input,placeholder:"Ask Claude...",placeholderTextColor:l.COLORS.TEXT_TERTIARY,value:y,onChangeText:B,onSubmitEditing:L,editable:!p,multiline:!0,maxLength:2e3,returnKeyType:"send",blurOnSubmit:!0}),p?(0,u.jsx)(s.TouchableOpacity,{style:[O.submitButton,O.stopButton],onPress:R,activeOpacity:.7,children:(0,u.jsx)(b,{})}):(0,u.jsx)(s.TouchableOpacity,{style:[O.submitButton,!w&&O.submitButtonDisabled],onPress:L,disabled:!w,activeOpacity:.7,children:(0,u.jsx)(T,{})})]})});function T(){return(0,u.jsxs)(s.View,{style:O.arrowIcon,children:[(0,u.jsx)(s.View,{style:O.arrowLine}),(0,u.jsx)(s.View,{style:O.arrowHead})]})}function b(){return(0,u.jsx)(s.View,{style:O.stopIcon})}var O=s.StyleSheet.create({container:{flexDirection:"row",alignItems:"flex-end",paddingHorizontal:l.LAYOUT.CONTENT_PADDING_H,paddingVertical:l.SPACING.MD,borderTopWidth:1,borderTopColor:l.COLORS.BORDER,backgroundColor:l.COLORS.BACKGROUND},input:{flex:1,backgroundColor:l.COLORS.BACKGROUND_INPUT,borderRadius:22,paddingHorizontal:18,paddingVertical:l.SPACING.MD,color:l.COLORS.TEXT_PRIMARY,fontSize:l.TYPOGRAPHY.SIZE_LG,maxHeight:100},submitButton:{width:l.SIZES.SUBMIT_BUTTON,height:l.SIZES.SUBMIT_BUTTON,borderRadius:l.SIZES.SUBMIT_BUTTON/2,backgroundColor:l.COLORS.BACKGROUND_BUTTON,alignItems:"center",justifyContent:"center",marginLeft:l.SPACING.SM+2},submitButtonDisabled:{opacity:.4},stopButton:{backgroundColor:l.COLORS.STATUS_NEUTRAL},stopIcon:{width:12,height:12,backgroundColor:l.COLORS.TEXT_PRIMARY,borderRadius:2},arrowIcon:{width:16,height:16,alignItems:"center",justifyContent:"center"},arrowLine:{width:2,height:10,backgroundColor:l.COLORS.TEXT_PRIMARY,borderRadius:1},arrowHead:{position:"absolute",top:0,width:0,height:0,borderLeftWidth:5,borderRightWidth:5,borderBottomWidth:6,borderLeftColor:"transparent",borderRightColor:"transparent",borderBottomColor:l.COLORS.TEXT_PRIMARY}})},486,[29,63,258,487,250]);
539
539
  __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"SPACING",{enumerable:!0,get:function(){return T}}),Object.defineProperty(e,"LAYOUT",{enumerable:!0,get:function(){return _}}),Object.defineProperty(e,"COLORS",{enumerable:!0,get:function(){return E}}),Object.defineProperty(e,"TYPOGRAPHY",{enumerable:!0,get:function(){return S}}),Object.defineProperty(e,"SIZES",{enumerable:!0,get:function(){return D}});var T={XS:4,SM:8,MD:12,LG:16,XL:20,XXL:24},_={CONTENT_PADDING_H:T.LG,SECTION_PADDING_V:T.MD,ELEMENT_GAP:T.MD,BORDER_RADIUS_LG:32,BORDER_RADIUS_MD:20,BORDER_RADIUS_SM:14},E={BACKGROUND:"#000",BACKGROUND_ELEVATED:"rgba(255,255,255,0.03)",BACKGROUND_INTERACTIVE:"rgba(255,255,255,0.08)",BACKGROUND_INPUT:"rgba(255,255,255,0.1)",BACKGROUND_BUTTON:"rgba(255,255,255,0.15)",TEXT_PRIMARY:"#fff",TEXT_SECONDARY:"rgba(255,255,255,0.6)",TEXT_TERTIARY:"rgba(255,255,255,0.5)",TEXT_MUTED:"rgba(255,255,255,0.4)",BORDER:"rgba(255,255,255,0.08)",STATUS_SUCCESS:"#30D158",STATUS_ERROR:"#FF3B30",STATUS_INFO:"#007AFF",STATUS_NEUTRAL:"#8E8E93"},S={SIZE_XS:11,SIZE_SM:13,SIZE_MD:14,SIZE_LG:15,SIZE_XL:17,WEIGHT_NORMAL:"400",WEIGHT_MEDIUM:"500",WEIGHT_SEMIBOLD:"600"},D={STATUS_DOT:8,CLOSE_BUTTON:30,SUBMIT_BUTTON:40,CTA_PADDING_V:6,CTA_PADDING_H:12}},487,[]);
540
540
  __d(function(g,r,_i,a,m,_e,d){"use strict";Object.defineProperty(_e,'__esModule',{value:!0}),_e.ResponseArea=function(e){var t=e.messages,i=e.currentParts,u=(0,l.useRef)(null),T=(0,l.useState)(!0),x=(0,n.default)(T,2),S=x[0],h=x[1],p=(0,l.useRef)(0),C=(0,l.useRef)(0),y=(0,l.useCallback)(e=>{var t=e.nativeEvent,n=t.contentOffset,l=t.contentSize,s=t.layoutMeasurement,i=l.height-s.height-n.y;h(i<50)},[]),P=(0,l.useCallback)((e,t)=>{p.current=t},[]),b=(0,l.useCallback)(e=>{C.current=e.nativeEvent.layout.height},[]);(0,l.useEffect)(()=>{if(S){var e=setTimeout(()=>{u.current?.scrollToEnd({animated:!1})},16);return()=>clearTimeout(e)}},[t,i,S]),(0,l.useEffect)(()=>{var e=t[t.length-1];"user_prompt"===e?.type&&(u.current?.scrollToEnd({animated:!0}),h(!0))},[t]),(0,l.useEffect)(()=>{var e=s.Keyboard.addListener("keyboardWillShow",()=>{S&&setTimeout(()=>{u.current?.scrollToEnd({animated:!0})},100)});return()=>e.remove()},[S]);var j=(0,l.useCallback)(()=>{u.current?.scrollToEnd({animated:!0}),h(!0)},[]);if(!(t.length>0||i.length>0))return(0,o.jsx)(s.View,{style:I.emptyContainer,children:(0,o.jsx)(s.Text,{style:I.emptyText,children:"Send a prompt to start coding with Claude"})});return(0,o.jsxs)(s.View,{style:I.wrapper,children:[(0,o.jsxs)(s.ScrollView,{ref:u,style:I.container,contentContainerStyle:I.content,showsVerticalScrollIndicator:!0,onScroll:y,onContentSizeChange:P,onLayout:b,scrollEventThrottle:16,children:[t.map((e,t)=>(0,o.jsx)(c,{message:e},t)),i.length>0&&(0,o.jsx)(f,{parts:i,isStreaming:!0})]}),!S&&(0,o.jsx)(s.TouchableOpacity,{style:I.scrollButton,onPress:j,activeOpacity:.8,children:(0,o.jsx)(s.Text,{style:I.scrollButtonText,children:"\u2193"})})]})};var e,t=r(d[0]),n=(e=t)&&e.__esModule?e:{default:e},l=r(d[1]),s=r(d[2]),i=r(d[3]),o=r(d[4]);function c(e){var t=e.message;switch(t.type){case"stream":case"status":default:return null;case"tool":return(0,o.jsx)(b,{tool:t});case"result":return(0,o.jsx)(j,{result:t});case"error":return(0,o.jsx)(s.View,{style:I.errorContainer,children:(0,o.jsx)(s.Text,{style:I.errorText,children:t.message})});case"user_prompt":return(0,o.jsx)(u,{message:t});case"history_result":return(0,o.jsx)(T,{message:t});case"assistant_parts":return(0,o.jsx)(p,{message:t});case"system_message":return(0,o.jsx)(x,{message:t})}}function u(e){var t=e.message;return(0,o.jsx)(s.View,{style:I.userPromptContainer,children:(0,o.jsx)(s.Text,{style:I.userPromptText,selectable:!0,children:t.content})})}function T(e){var t=e.message;return(0,o.jsx)(s.View,{style:I.resultContainer,children:(0,o.jsx)(S,{content:t.content})})}function x(e){var t=e.message;return"error"===t.messageType?(0,o.jsx)(s.View,{style:I.errorContainer,children:(0,o.jsx)(s.Text,{style:I.errorText,children:t.content})}):(0,o.jsx)(s.View,{style:I.systemContainer,children:(0,o.jsx)(s.Text,{style:I.systemText,children:t.content})})}function S(e){for(var t=e.content,l=e.isStreaming,i=t.split('\n'),c=[],u=0;u<i.length;){var T=i[u],x=T.trim(),S=x.match(/^(\d+)\.\s+(.+)$/);if(S){var f=(0,n.default)(S,3),p=f[1],C=f[2];c.push((0,o.jsxs)(s.View,{style:I.listItem,children:[(0,o.jsxs)(s.Text,{style:I.listNumber,children:[p,"."]}),(0,o.jsx)(s.Text,{style:I.listText,selectable:!0,children:h(C)})]},u)),u++}else{var y=x.match(/^[-*]\s+(.+)$/);if(y)c.push((0,o.jsxs)(s.View,{style:I.listItem,children:[(0,o.jsx)(s.Text,{style:I.listBullet,children:"\u2022"}),(0,o.jsx)(s.Text,{style:I.listText,selectable:!0,children:h(y[1])})]},u)),u++;else if(x.startsWith('```')){var P=[],b=x.slice(3).trim();for(u++;u<i.length&&!i[u].trim().startsWith('```');)P.push(i[u]),u++;c.push((0,o.jsxs)(s.View,{style:I.codeBlock,children:[b&&(0,o.jsx)(s.Text,{style:I.codeLang,children:b}),(0,o.jsx)(s.Text,{style:I.codeText,selectable:!0,children:P.join('\n')})]},`code-${u}`)),u++}else x?(c.push((0,o.jsx)(s.Text,{style:I.responseText,selectable:!0,children:h(T)},u)),u++):(c.push((0,o.jsx)(s.View,{style:I.paragraphBreak},u)),u++)}}return(0,o.jsxs)(s.View,{style:I.formattedContainer,children:[c,l&&(0,o.jsx)(s.View,{style:I.cursor})]})}function h(e){var t=e.split(/(`[^`]+`)/g);return 1===t.length?e:t.map((e,t)=>e.startsWith('`')&&e.endsWith('`')?(0,o.jsx)(s.Text,{style:I.inlineCode,children:e.slice(1,-1)},t):e)}function f(e){var t=e.parts,n=e.isStreaming;return(0,o.jsx)(s.View,{style:I.partsContainer,children:t.map((e,l)=>{if("text"===e.type){var i=l===t.length-1;return(0,o.jsx)(s.View,{style:I.messageContainer,children:(0,o.jsx)(S,{content:e.content,isStreaming:n&&i})},e.id)}return"tool"===e.type?(0,o.jsx)(P,{part:e},e.id):null})})}function p(e){var t=e.message;return(0,o.jsxs)(s.View,{style:I.resultContainer,children:[(0,o.jsx)(f,{parts:t.parts,isStreaming:!1}),!t.isComplete&&(0,o.jsx)(s.Text,{style:I.interruptedText,children:"(interrupted)"})]})}function C(e,t){var n=e=>e.split('/').pop()||e;switch(e){case"Read":return{label:"read",value:n(t?.file_path||"file")};case"Edit":return{label:"edit",value:n(t?.file_path||"file")};case"Write":return{label:"write",value:n(t?.file_path||"file")};case"Bash":var l=t?.command||"";return{label:"$",value:l.length>45?l.slice(0,45)+"\u2026":l};case"Glob":return{label:"glob",value:t?.pattern||"*"};case"Grep":return{label:"grep",value:t?.pattern||"search"};case"Task":return{label:"agent",value:t?.description||"task"};default:return{label:e.toLowerCase(),value:""}}}function y(e){var t=e.toolName,n=e.input,l=e.isFailed,i=C(t,n),c=i.label,u=i.value;return(0,o.jsxs)(s.View,{style:I.toolLine,children:[(0,o.jsx)(s.Text,{style:l?I.toolLabelFailed:I.toolLabel,children:c}),(0,o.jsx)(s.Text,{style:l?I.toolValueFailed:I.toolValue,numberOfLines:1,children:u}),l&&(0,o.jsx)(s.Text,{style:I.toolLabelFailed,children:" \u2715"})]})}function P(e){var t=e.part;return"started"===t.status?null:(0,o.jsx)(y,{toolName:t.toolName,input:t.input,isFailed:"failed"===t.status})}function b(e){var t=e.tool;return"started"===t.status?null:(0,o.jsx)(y,{toolName:t.toolName,input:t.input,isFailed:"failed"===t.status})}function j(e){var t=e.result;return!t.success&&t.error?(0,o.jsx)(s.View,{style:I.errorContainer,children:(0,o.jsx)(s.Text,{style:I.errorText,children:t.error})}):(0,o.jsxs)(s.View,{style:I.resultContainer,children:[t.result&&(0,o.jsx)(s.Text,{style:I.responseText,selectable:!0,children:t.result}),(void 0!==t.costUsd||void 0!==t.durationMs)&&(0,o.jsxs)(s.Text,{style:I.metaText,children:[void 0!==t.durationMs&&`${t.durationMs}ms`,void 0!==t.costUsd&&void 0!==t.durationMs&&" \u2022 ",void 0!==t.costUsd&&`$${t.costUsd.toFixed(4)}`]})]})}var I=s.StyleSheet.create({wrapper:{flex:1,position:"relative"},container:{flex:1,backgroundColor:i.COLORS.BACKGROUND},content:{padding:i.LAYOUT.CONTENT_PADDING_H,paddingBottom:i.SPACING.XXL},emptyContainer:{flex:1,alignItems:"center",justifyContent:"center",padding:i.SPACING.XXL},emptyText:{color:i.COLORS.TEXT_MUTED,fontSize:i.TYPOGRAPHY.SIZE_LG,textAlign:"center",lineHeight:22},messageContainer:{flexDirection:"row",flexWrap:"wrap"},responseText:{color:"rgba(255,255,255,0.95)",fontSize:i.TYPOGRAPHY.SIZE_LG,lineHeight:22},cursor:{width:2,height:18,backgroundColor:i.COLORS.TEXT_PRIMARY,marginLeft:2,opacity:.7},resultContainer:{marginTop:i.SPACING.SM},partsContainer:{},formattedContainer:{flexDirection:"column"},listItem:{flexDirection:"row",marginVertical:i.SPACING.XS/2,paddingLeft:i.SPACING.SM},listNumber:{color:i.COLORS.TEXT_MUTED,fontSize:i.TYPOGRAPHY.SIZE_LG,lineHeight:22,width:24,fontWeight:i.TYPOGRAPHY.WEIGHT_MEDIUM},listBullet:{color:i.COLORS.TEXT_MUTED,fontSize:i.TYPOGRAPHY.SIZE_LG,lineHeight:22,width:18},listText:{flex:1,color:"rgba(255,255,255,0.95)",fontSize:i.TYPOGRAPHY.SIZE_LG,lineHeight:22},codeBlock:{backgroundColor:"rgba(255,255,255,0.06)",borderRadius:i.SPACING.SM,padding:i.SPACING.MD,marginVertical:i.SPACING.SM},codeLang:{color:i.COLORS.TEXT_MUTED,fontSize:i.TYPOGRAPHY.SIZE_XS,fontFamily:"Menlo",marginBottom:i.SPACING.XS,textTransform:"uppercase"},codeText:{color:"rgba(255,255,255,0.85)",fontSize:i.TYPOGRAPHY.SIZE_SM,fontFamily:"Menlo",lineHeight:18},inlineCode:{backgroundColor:"rgba(255,255,255,0.1)",color:"rgba(255,255,255,0.9)",fontFamily:"Menlo",fontSize:i.TYPOGRAPHY.SIZE_MD,paddingHorizontal:4,borderRadius:3},paragraphBreak:{height:i.SPACING.SM},interruptedText:{color:i.COLORS.TEXT_MUTED,fontSize:i.TYPOGRAPHY.SIZE_XS+1,fontStyle:"italic",marginTop:i.SPACING.XS},metaText:{color:i.COLORS.TEXT_MUTED,fontSize:i.TYPOGRAPHY.SIZE_XS+1,marginTop:i.SPACING.SM+2},errorContainer:{backgroundColor:"rgba(255,59,48,0.15)",borderRadius:i.SPACING.MD,padding:i.SPACING.MD,marginVertical:i.SPACING.SM-2},errorText:{color:"#FF6B6B",fontSize:i.TYPOGRAPHY.SIZE_MD},systemContainer:{backgroundColor:"rgba(255,255,255,0.05)",borderRadius:i.SPACING.MD,padding:i.SPACING.MD,marginVertical:i.SPACING.SM-2},systemText:{color:i.COLORS.TEXT_TERTIARY,fontSize:i.TYPOGRAPHY.SIZE_MD,fontStyle:"italic"},toolLine:{flexDirection:"row",alignItems:"center",marginVertical:i.SPACING.XS},toolLabel:{color:i.COLORS.TEXT_MUTED,fontSize:i.TYPOGRAPHY.SIZE_XS+1,fontFamily:"Menlo",marginRight:i.SPACING.SM,minWidth:36},toolLabelFailed:{color:"rgba(255,100,100,0.6)",fontSize:i.TYPOGRAPHY.SIZE_XS+1,fontFamily:"Menlo",marginRight:i.SPACING.SM,minWidth:36},toolValue:{color:"rgba(255,255,255,0.7)",fontSize:i.TYPOGRAPHY.SIZE_SM,fontFamily:"Menlo",flexShrink:1},toolValueFailed:{color:"rgba(255,100,100,0.7)",fontSize:i.TYPOGRAPHY.SIZE_SM,fontFamily:"Menlo",flexShrink:1},userPromptContainer:{backgroundColor:"rgba(0,122,255,0.15)",borderRadius:i.LAYOUT.BORDER_RADIUS_SM+2,padding:i.SPACING.MD,marginVertical:i.SPACING.SM,alignSelf:"flex-end",maxWidth:"85%"},userPromptText:{color:i.COLORS.TEXT_PRIMARY,fontSize:i.TYPOGRAPHY.SIZE_LG,lineHeight:20},scrollButton:{position:"absolute",bottom:i.LAYOUT.CONTENT_PADDING_H,alignSelf:"center",left:"50%",marginLeft:-18,width:36,height:36,borderRadius:18,backgroundColor:"rgba(255,255,255,0.12)",borderWidth:1,borderColor:"rgba(255,255,255,0.2)",alignItems:"center",justifyContent:"center"},scrollButtonText:{color:i.COLORS.TEXT_PRIMARY,fontSize:18,fontWeight:i.TYPOGRAPHY.WEIGHT_SEMIBOLD}})},488,[29,63,258,487,250]);
541
541
  __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.GitChangesTab=function(c){var f=c.changes,x=c.onDiscard;if(!(f.length>0))return(0,n.jsxs)(t.View,{style:s.emptyContainer,children:[(0,n.jsx)(t.Text,{style:s.emptyTitle,children:"No uncommitted changes"}),(0,n.jsx)(t.Text,{style:s.emptySubtext,children:"Your working directory is clean"})]});return(0,n.jsxs)(t.View,{style:s.container,children:[(0,n.jsx)(t.ScrollView,{style:s.fileList,contentContainerStyle:s.fileListContent,children:f.map((c,f)=>(0,n.jsxs)(t.View,{style:s.fileRow,children:[(0,n.jsx)(t.Text,{style:[s.statusIcon,{color:l[c.status]}],children:o[c.status]}),(0,n.jsx)(t.Text,{style:s.fileName,numberOfLines:1,children:c.file})]},`${c.file}-${f}`))}),(0,n.jsxs)(t.View,{style:s.footer,children:[(0,n.jsx)(t.TouchableOpacity,{style:s.discardButton,onPress:x,children:(0,n.jsx)(t.Text,{style:s.discardText,children:"Discard All Changes"})}),(0,n.jsx)(t.Text,{style:s.warningText,children:"Note: Discarding won't reset memory"})]})]})},r(d[0]);var t=r(d[1]),n=r(d[2]),o={added:"A",modified:"M",deleted:"D",renamed:"R",untracked:"?"},l={added:"#30D158",modified:"#FFD60A",deleted:"#FF453A",renamed:"#BF5AF2",untracked:"#8E8E93"};var s=t.StyleSheet.create({container:{flex:1,backgroundColor:"#000"},emptyContainer:{flex:1,backgroundColor:"#000",alignItems:"center",justifyContent:"center",padding:24},emptyTitle:{color:"rgba(255,255,255,0.6)",fontSize:16,fontWeight:"500",marginBottom:8},emptySubtext:{color:"rgba(255,255,255,0.4)",fontSize:14},fileList:{flex:1},fileListContent:{padding:16},fileRow:{flexDirection:"row",alignItems:"center",paddingVertical:8,borderBottomWidth:1,borderBottomColor:"rgba(255,255,255,0.06)"},statusIcon:{width:20,fontSize:13,fontWeight:"600",fontFamily:"Menlo"},fileName:{flex:1,color:"rgba(255,255,255,0.8)",fontSize:14,fontFamily:"Menlo"},footer:{padding:16,borderTopWidth:1,borderTopColor:"rgba(255,255,255,0.08)",alignItems:"center"},discardButton:{backgroundColor:"rgba(255,59,48,0.15)",borderRadius:12,paddingVertical:12,paddingHorizontal:24,marginBottom:8},discardText:{color:"#FF3B30",fontSize:15,fontWeight:"500"},warningText:{color:"rgba(255,255,255,0.3)",fontSize:12}})},489,[63,258,250]);
542
- __d(function(g,r,i,a,m,_e,d){"use strict";function t(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(_e,'__esModule',{value:!0}),Object.defineProperty(_e,"WebSocketClient",{enumerable:!0,get:function(){return n}}),_e.getWebSocketClient=function(){return o},_e.createWebSocketClient=function(t){o&&o.disconnect();return o=new n(t)};var e=t(r(d[0])),s=t(r(d[1])),n=(function(){return(0,s.default)(function t(s){(0,e.default)(this,t),this.ws=null,this.reconnectAttempts=0,this.reconnectTimeout=null,this._status="disconnected",this.shouldReconnect=!0,this.options={reconnectInterval:3e3,maxReconnectAttempts:10,onConnect:()=>{},onDisconnect:()=>{},onMessage:()=>{},onError:()=>{},onStatusChange:()=>{},...s}},[{key:"status",get:function(){return this._status}},{key:"setStatus",value:function(t){this._status=t,this.options.onStatusChange(t)}},{key:"connect",value:function(){if(this.ws?.readyState!==WebSocket.OPEN){this.shouldReconnect=!0,this.setStatus("connecting");try{this.ws=new WebSocket(this.options.url),this.ws.onopen=()=>{this.reconnectAttempts=0,this.setStatus("connected"),this.options.onConnect()},this.ws.onclose=()=>{this.setStatus("disconnected"),this.options.onDisconnect(),this.attemptReconnect()},this.ws.onerror=()=>{var t=new Error("WebSocket error");this.options.onError(t)},this.ws.onmessage=t=>{try{var e=JSON.parse(t.data);this.handleMessage(e)}catch(t){console.error("[expo-air] Failed to parse message:",t)}}}catch(t){this.options.onError(t),this.attemptReconnect()}}}},{key:"handleMessage",value:function(t){"status"===t.type?"processing"===t.status?this.setStatus("processing"):"idle"!==t.status&&"connected"!==t.status||this.setStatus("connected"):"result"===t.type||"error"===t.type?this.setStatus("connected"):"stopped"!==t.type&&"session_cleared"!==t.type||this.setStatus("connected"),this.options.onMessage(t)}},{key:"attemptReconnect",value:function(){this.shouldReconnect&&(this.reconnectAttempts>=this.options.maxReconnectAttempts?console.log("[expo-air] Max reconnect attempts reached"):(this.reconnectTimeout&&clearTimeout(this.reconnectTimeout),this.reconnectAttempts++,console.log(`[expo-air] Reconnecting... (attempt ${this.reconnectAttempts}/${this.options.maxReconnectAttempts})`),this.reconnectTimeout=setTimeout(()=>{this.connect()},this.options.reconnectInterval)))}},{key:"disconnect",value:function(){this.shouldReconnect=!1,this.reconnectTimeout&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=null),this.ws&&(this.ws.close(),this.ws=null),this.setStatus("disconnected")}},{key:"sendPrompt",value:function(t){if(this.ws&&this.ws.readyState===WebSocket.OPEN){var e={type:"prompt",content:t,id:Math.random().toString(36).substring(2,15)};this.ws.send(JSON.stringify(e)),this.setStatus("processing")}else this.options.onError(new Error("Not connected"))}},{key:"requestNewSession",value:function(){this.ws&&this.ws.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify({type:"new_session"})):this.options.onError(new Error("Not connected"))}},{key:"requestStop",value:function(){this.ws&&this.ws.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify({type:"stop"})):this.options.onError(new Error("Not connected"))}},{key:"requestDiscardChanges",value:function(){this.ws&&this.ws.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify({type:"discard_changes"})):this.options.onError(new Error("Not connected"))}},{key:"sendPushToken",value:function(t){this.ws&&this.ws.readyState===WebSocket.OPEN&&this.ws.send(JSON.stringify({type:"register_push_token",token:t}))}},{key:"isConnected",value:function(){return this.ws?.readyState===WebSocket.OPEN}}])})();var o=null},490,[8,9]);
542
+ __d(function(g,r,i,a,m,_e,d){"use strict";function t(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(_e,'__esModule',{value:!0}),Object.defineProperty(_e,"WebSocketClient",{enumerable:!0,get:function(){return n}}),_e.getWebSocketClient=function(){return o},_e.createWebSocketClient=function(t){o&&o.disconnect();return o=new n(t)};var e=t(r(d[0])),s=t(r(d[1])),n=(function(){return(0,s.default)(function t(s){(0,e.default)(this,t),this.ws=null,this.reconnectAttempts=0,this.reconnectTimeout=null,this._status="disconnected",this.shouldReconnect=!0,this.options={reconnectInterval:3e3,maxReconnectAttempts:10,onConnect:()=>{},onDisconnect:()=>{},onMessage:()=>{},onError:()=>{},onStatusChange:()=>{},...s}},[{key:"status",get:function(){return this._status}},{key:"setStatus",value:function(t){this._status=t,this.options.onStatusChange(t)}},{key:"connect",value:function(){if(this.ws?.readyState!==WebSocket.OPEN){this.shouldReconnect=!0,this.setStatus("connecting");try{this.ws=new WebSocket(this.options.url),this.ws.onopen=()=>{this.reconnectAttempts=0,this.setStatus("connected"),this.options.onConnect()},this.ws.onclose=()=>{this.setStatus("disconnected"),this.options.onDisconnect(),this.attemptReconnect()},this.ws.onerror=()=>{var t=new Error("WebSocket error");this.options.onError(t)},this.ws.onmessage=t=>{try{var e=JSON.parse(t.data);this.handleMessage(e)}catch(t){console.error("[expo-air] Failed to parse message:",t)}}}catch(t){this.options.onError(t),this.attemptReconnect()}}}},{key:"handleMessage",value:function(t){"status"===t.type?"processing"===t.status?this.setStatus("processing"):"idle"!==t.status&&"connected"!==t.status||this.setStatus("connected"):"result"===t.type||"error"===t.type?this.setStatus("connected"):"stopped"!==t.type&&"session_cleared"!==t.type||this.setStatus("connected"),this.options.onMessage(t)}},{key:"attemptReconnect",value:function(){this.shouldReconnect&&(this.reconnectAttempts>=this.options.maxReconnectAttempts?console.log("[expo-air] Max reconnect attempts reached"):(this.reconnectTimeout&&clearTimeout(this.reconnectTimeout),this.reconnectAttempts++,console.log(`[expo-air] Reconnecting... (attempt ${this.reconnectAttempts}/${this.options.maxReconnectAttempts})`),this.reconnectTimeout=setTimeout(()=>{this.connect()},this.options.reconnectInterval)))}},{key:"disconnect",value:function(){this.shouldReconnect=!1,this.reconnectTimeout&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=null),this.ws&&(this.ws.close(),this.ws=null),this.setStatus("disconnected")}},{key:"sendPrompt",value:function(t){if(this.ws&&this.ws.readyState===WebSocket.OPEN){var e={type:"prompt",content:t,id:Math.random().toString(36).substring(2,15)};this.ws.send(JSON.stringify(e)),this.setStatus("processing")}else this.options.onError(new Error("Not connected"))}},{key:"requestNewSession",value:function(){this.ws&&this.ws.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify({type:"new_session"})):this.options.onError(new Error("Not connected"))}},{key:"requestStop",value:function(){this.ws&&this.ws.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify({type:"stop"})):this.options.onError(new Error("Not connected"))}},{key:"requestDiscardChanges",value:function(){this.ws&&this.ws.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify({type:"discard_changes"})):this.options.onError(new Error("Not connected"))}},{key:"sendPushToken",value:function(t){this.ws&&this.ws.readyState===WebSocket.OPEN&&this.ws.send(JSON.stringify({type:"register_push_token",token:t}))}},{key:"requestBranches",value:function(){this.ws&&this.ws.readyState===WebSocket.OPEN&&this.ws.send(JSON.stringify({type:"list_branches"}))}},{key:"requestSwitchBranch",value:function(t){this.ws&&this.ws.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify({type:"switch_branch",branchName:t})):this.options.onError(new Error("Not connected"))}},{key:"requestCreateBranch",value:function(t){this.ws&&this.ws.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify({type:"create_branch",branchName:t})):this.options.onError(new Error("Not connected"))}},{key:"isConnected",value:function(){return this.ws?.readyState===WebSocket.OPEN}}])})();var o=null},490,[8,9]);
543
543
  __d(function(g,r,i,a,m,_e,d){"use strict";Object.defineProperty(_e,'__esModule',{value:!0}),_e.requestPushToken=function(){return u.apply(this,arguments)},_e.setupTapHandler=function(e){return console.log("[expo-air] setupTapHandler: tap handling managed by main app"),()=>{}};var e,n=r(d[0]),o=(e=n)&&e.__esModule?e:{default:e},t=r(d[1]).NativeModules.WidgetBridge;function u(){return(u=(0,o.default)(function*(){try{if(!t?.requestPushToken)return console.log("[expo-air] WidgetBridge.requestPushToken not available"),null;console.log("[expo-air] Requesting push token via native bridge");var e=yield t.requestPushToken();return e?(console.log("[expo-air] Got push token:",e),e):(console.log("[expo-air] Push notification permission denied or token unavailable"),null)}catch(e){return console.error("[expo-air] Failed to get push token:",e),null}})).apply(this,arguments)}},491,[346,258]);
544
+ __d(function(g,r,i,a,m,_e,d){"use strict";Object.defineProperty(_e,'__esModule',{value:!0}),_e.BranchSwitcher=function(e){var t=e.branches,h=(e.currentBranch,e.onSelect),b=e.onCreate,u=e.onClose,C=e.error,I=(0,n.useState)(!1),T=(0,o.default)(I,2),p=T[0],P=T[1],O=(0,n.useState)(""),x=(0,o.default)(O,2),A=x[0],f=x[1],y=()=>{var e=A.trim();e&&(b(e),f(""),P(!1))};return(0,s.jsxs)(l.View,{style:S.overlay,children:[(0,s.jsx)(l.TouchableOpacity,{style:S.backdrop,onPress:u,activeOpacity:1}),(0,s.jsxs)(l.View,{style:S.dropdown,children:[C&&(0,s.jsx)(l.View,{style:S.errorBanner,children:(0,s.jsx)(l.Text,{style:S.errorText,numberOfLines:2,children:C})}),(0,s.jsx)(l.ScrollView,{style:S.branchList,bounces:!1,children:t.map((e,t)=>(0,s.jsxs)(l.TouchableOpacity,{style:[S.branchItem,e.isCurrent&&S.branchItemCurrent,0===t&&S.branchItemFirst],onPress:()=>{e.isCurrent||h(e.name)},activeOpacity:e.isCurrent?1:.6,children:[(0,s.jsxs)(l.View,{style:S.branchInfo,children:[(0,s.jsx)(l.Text,{style:[S.branchName,e.isCurrent&&S.branchNameCurrent],numberOfLines:1,children:e.name}),e.prNumber&&(0,s.jsx)(l.View,{style:S.prBadge,children:(0,s.jsxs)(l.Text,{style:S.prBadgeText,children:["#",e.prNumber]})})]}),e.isCurrent&&(0,s.jsx)(l.Text,{style:S.currentIndicator,children:"\u2713"})]},e.name))}),(0,s.jsx)(l.View,{style:S.createSection,children:p?(0,s.jsxs)(l.View,{style:S.createInputRow,children:[(0,s.jsx)(l.TextInput,{style:S.createInput,value:A,onChangeText:f,placeholder:"branch-name",placeholderTextColor:c.COLORS.TEXT_MUTED,autoFocus:!0,autoCapitalize:"none",autoCorrect:!1,onSubmitEditing:y,returnKeyType:"done"}),(0,s.jsx)(l.TouchableOpacity,{style:[S.createConfirmButton,!A.trim()&&S.createConfirmDisabled],onPress:y,disabled:!A.trim(),children:(0,s.jsx)(l.Text,{style:S.createConfirmText,children:"Create"})})]}):(0,s.jsx)(l.TouchableOpacity,{style:S.createButton,onPress:()=>P(!0),children:(0,s.jsx)(l.Text,{style:S.createButtonText,children:"+ New branch from main"})})})]})]})};var e,t=r(d[0]),o=(e=t)&&e.__esModule?e:{default:e},n=r(d[1]),l=r(d[2]),c=r(d[3]),s=r(d[4]);var S=l.StyleSheet.create({overlay:{...l.StyleSheet.absoluteFillObject,zIndex:100},backdrop:{...l.StyleSheet.absoluteFillObject,backgroundColor:"rgba(0,0,0,0.3)"},dropdown:{position:"absolute",top:49,left:c.SPACING.SM,right:c.SPACING.SM,maxHeight:"60%",backgroundColor:"#1C1C1E",borderRadius:c.LAYOUT.BORDER_RADIUS_SM,borderWidth:1,borderColor:"rgba(255,255,255,0.12)",overflow:"hidden"},branchList:{maxHeight:300},branchItem:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingHorizontal:c.SPACING.LG,paddingVertical:c.SPACING.MD+2,borderBottomWidth:l.StyleSheet.hairlineWidth,borderBottomColor:"rgba(255,255,255,0.06)"},branchItemFirst:{paddingTop:c.SPACING.MD+2},branchItemCurrent:{backgroundColor:"rgba(255,255,255,0.06)"},branchInfo:{flex:1,flexDirection:"row",alignItems:"center",gap:c.SPACING.SM},branchName:{color:"rgba(255,255,255,0.85)",fontSize:c.TYPOGRAPHY.SIZE_MD,fontWeight:c.TYPOGRAPHY.WEIGHT_NORMAL,flexShrink:1},branchNameCurrent:{color:c.COLORS.TEXT_PRIMARY,fontWeight:c.TYPOGRAPHY.WEIGHT_MEDIUM},prBadge:{backgroundColor:"rgba(0,122,255,0.15)",paddingHorizontal:c.SPACING.SM,paddingVertical:2,borderRadius:8},prBadgeText:{color:c.COLORS.STATUS_INFO,fontSize:c.TYPOGRAPHY.SIZE_XS,fontWeight:c.TYPOGRAPHY.WEIGHT_MEDIUM},currentIndicator:{color:c.COLORS.STATUS_SUCCESS,fontSize:c.TYPOGRAPHY.SIZE_SM,marginLeft:c.SPACING.SM},createSection:{paddingHorizontal:c.SPACING.LG,paddingVertical:c.SPACING.MD,borderTopWidth:l.StyleSheet.hairlineWidth,borderTopColor:"rgba(255,255,255,0.08)"},createButton:{paddingVertical:c.SPACING.XS},createButtonText:{color:c.COLORS.STATUS_INFO,fontSize:c.TYPOGRAPHY.SIZE_MD,fontWeight:c.TYPOGRAPHY.WEIGHT_MEDIUM},createInputRow:{flexDirection:"row",alignItems:"center",gap:c.SPACING.SM},createInput:{flex:1,backgroundColor:"rgba(255,255,255,0.08)",color:c.COLORS.TEXT_PRIMARY,fontSize:c.TYPOGRAPHY.SIZE_MD,paddingHorizontal:c.SPACING.MD,paddingVertical:c.SPACING.SM,borderRadius:10},createConfirmButton:{backgroundColor:c.COLORS.STATUS_INFO,paddingHorizontal:c.SPACING.MD,paddingVertical:c.SPACING.SM,borderRadius:10},createConfirmDisabled:{opacity:.4},createConfirmText:{color:c.COLORS.TEXT_PRIMARY,fontSize:c.TYPOGRAPHY.SIZE_SM,fontWeight:c.TYPOGRAPHY.WEIGHT_SEMIBOLD},errorBanner:{backgroundColor:"rgba(255,59,48,0.15)",paddingHorizontal:c.SPACING.LG,paddingVertical:c.SPACING.SM,borderBottomWidth:l.StyleSheet.hairlineWidth,borderBottomColor:"rgba(255,59,48,0.3)"},errorText:{color:"#FF6B6B",fontSize:c.TYPOGRAPHY.SIZE_SM}})},492,[29,63,258,487,250]);
544
545
  __r(1);
545
546
  __r(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@10play/expo-air",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Vibe Coding for React-Native",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -78,9 +78,46 @@ const withAppDelegatePatch = (config) => {
78
78
  },
79
79
  ]);
80
80
  };
81
+ // Inject HMR auto-reconnect import into the app's JS entry point
82
+ const withHMRReconnect = (config) => {
83
+ return (0, config_plugins_1.withDangerousMod)(config, [
84
+ "ios",
85
+ async (config) => {
86
+ const projectRoot = config.modRequest.projectRoot;
87
+ const hmrImport = `import "@10play/expo-air/build/hmrReconnect";\n`;
88
+ // Common entry points for Expo Router and vanilla RN apps
89
+ const candidates = [
90
+ "app/_layout.tsx",
91
+ "app/_layout.js",
92
+ "App.tsx",
93
+ "App.js",
94
+ "index.tsx",
95
+ "index.js",
96
+ ];
97
+ for (const candidate of candidates) {
98
+ const entryPath = path.join(projectRoot, candidate);
99
+ if (fs.existsSync(entryPath)) {
100
+ let content = fs.readFileSync(entryPath, "utf-8");
101
+ if (content.includes("@10play/expo-air/build/hmrReconnect")) {
102
+ // Already injected
103
+ return config;
104
+ }
105
+ content = hmrImport + content;
106
+ fs.writeFileSync(entryPath, content);
107
+ console.log(`[expo-air] Injected HMR auto-reconnect into ${candidate}`);
108
+ return config;
109
+ }
110
+ }
111
+ console.warn("[expo-air] Could not find app entry point for HMR reconnect injection");
112
+ return config;
113
+ },
114
+ ]);
115
+ };
81
116
  const withExpoAir = (config) => {
82
117
  // First patch AppDelegate
83
118
  config = withAppDelegatePatch(config);
119
+ // Inject HMR auto-reconnect
120
+ config = withHMRReconnect(config);
84
121
  // NOTE: We do NOT add aps-environment entitlement here.
85
122
  // Adding "development" would break production builds (entitlement mismatch with distribution profile).
86
123
  // If developer wants push notifications, they should enable Push Notifications capability in Xcode,
@@ -9,11 +9,13 @@ import {
9
9
  type ServerMessage,
10
10
  type ConnectionStatus,
11
11
  type GitChange,
12
+ type BranchInfo,
12
13
  type AnyConversationEntry,
13
14
  type AssistantPart,
14
15
  type AssistantPartsMessage,
15
16
  } from "./services/websocket";
16
17
  import { requestPushToken, setupTapHandler } from "./services/notifications";
18
+ import { BranchSwitcher } from "./components/BranchSwitcher";
17
19
  import { SPACING, LAYOUT, COLORS, TYPOGRAPHY, SIZES } from "./constants/design";
18
20
 
19
21
  // WidgetBridge is a simple native module available in the widget runtime
@@ -58,6 +60,9 @@ export function BubbleContent({
58
60
  const [hasPR, setHasPR] = useState(false);
59
61
  const [prUrl, setPrUrl] = useState<string | undefined>();
60
62
  const [activeTab, setActiveTab] = useState<TabType>("chat");
63
+ const [showBranchSwitcher, setShowBranchSwitcher] = useState(false);
64
+ const [branches, setBranches] = useState<BranchInfo[]>([]);
65
+ const [branchError, setBranchError] = useState<string | null>(null);
61
66
  const pushTokenSentRef = useRef(false);
62
67
  const partIdCounter = useRef(0);
63
68
  // Use refs to avoid stale closure issues in handleMessage callback
@@ -283,6 +288,25 @@ export function BubbleContent({
283
288
  setHasPR(message.hasPR);
284
289
  setPrUrl(message.prUrl);
285
290
  break;
291
+ case "branches_list":
292
+ setBranches(message.branches);
293
+ break;
294
+ case "branch_switched":
295
+ if (message.success) {
296
+ setShowBranchSwitcher(false);
297
+ setBranchError(null);
298
+ } else if (message.error) {
299
+ setBranchError(message.error);
300
+ }
301
+ break;
302
+ case "branch_created":
303
+ if (message.success) {
304
+ setShowBranchSwitcher(false);
305
+ setBranchError(null);
306
+ } else if (message.error) {
307
+ setBranchError(message.error);
308
+ }
309
+ break;
286
310
  }
287
311
  }, [finalizeCurrentParts]);
288
312
 
@@ -356,6 +380,33 @@ export function BubbleContent({
356
380
  }
357
381
  }, []);
358
382
 
383
+ const handleBranchPress = useCallback(() => {
384
+ setShowBranchSwitcher((prev) => !prev);
385
+ // Fetch branches when opening (side-effect outside state updater)
386
+ if (!showBranchSwitcher) {
387
+ const client = getWebSocketClient();
388
+ if (client) {
389
+ client.requestBranches();
390
+ }
391
+ }
392
+ }, [showBranchSwitcher]);
393
+
394
+ const handleBranchSelect = useCallback((name: string) => {
395
+ setBranchError(null);
396
+ const client = getWebSocketClient();
397
+ if (client) {
398
+ client.requestSwitchBranch(name);
399
+ }
400
+ }, []);
401
+
402
+ const handleBranchCreate = useCallback((name: string) => {
403
+ setBranchError(null);
404
+ const client = getWebSocketClient();
405
+ if (client) {
406
+ client.requestCreateBranch(name);
407
+ }
408
+ }, []);
409
+
359
410
  // Collapsed: Just a pulsing indicator, no text
360
411
  if (!expanded) {
361
412
  return (
@@ -371,6 +422,7 @@ export function BubbleContent({
371
422
  <Header
372
423
  status={status}
373
424
  branchName={branchName}
425
+ onBranchPress={handleBranchPress}
374
426
  />
375
427
  <TabBar
376
428
  activeTab={activeTab}
@@ -400,6 +452,16 @@ export function BubbleContent({
400
452
  isProcessing={status === "processing"}
401
453
  />
402
454
  )}
455
+ {showBranchSwitcher && (
456
+ <BranchSwitcher
457
+ branches={branches}
458
+ currentBranch={branchName}
459
+ onSelect={handleBranchSelect}
460
+ onCreate={handleBranchCreate}
461
+ onClose={() => { setShowBranchSwitcher(false); setBranchError(null); }}
462
+ error={branchError}
463
+ />
464
+ )}
403
465
  </View>
404
466
  );
405
467
  }
@@ -407,9 +469,10 @@ export function BubbleContent({
407
469
  interface HeaderProps {
408
470
  status: ConnectionStatus;
409
471
  branchName: string;
472
+ onBranchPress: () => void;
410
473
  }
411
474
 
412
- function Header({ status, branchName }: HeaderProps) {
475
+ function Header({ status, branchName, onBranchPress }: HeaderProps) {
413
476
  const statusColors = {
414
477
  disconnected: COLORS.STATUS_ERROR,
415
478
  connecting: COLORS.STATUS_INFO,
@@ -423,9 +486,12 @@ function Header({ status, branchName }: HeaderProps) {
423
486
  <Text style={styles.closeButtonText}>✕</Text>
424
487
  </TouchableOpacity>
425
488
 
426
- <Text style={styles.branchName} numberOfLines={1}>
427
- {branchName}
428
- </Text>
489
+ <TouchableOpacity style={styles.branchButton} onPress={onBranchPress}>
490
+ <Text style={styles.branchName} numberOfLines={1}>
491
+ {branchName}
492
+ </Text>
493
+ <Text style={styles.branchChevron}>▾</Text>
494
+ </TouchableOpacity>
429
495
 
430
496
  <View style={[styles.statusDot, { backgroundColor: statusColors[status] }]} />
431
497
  </View>
@@ -686,12 +752,22 @@ const styles = StyleSheet.create({
686
752
  fontSize: TYPOGRAPHY.SIZE_MD,
687
753
  fontWeight: TYPOGRAPHY.WEIGHT_SEMIBOLD,
688
754
  },
689
- branchName: {
755
+ branchButton: {
690
756
  flex: 1,
757
+ flexDirection: "row",
758
+ alignItems: "center",
759
+ },
760
+ branchName: {
761
+ flexShrink: 1,
691
762
  color: COLORS.TEXT_SECONDARY,
692
763
  fontSize: TYPOGRAPHY.SIZE_MD,
693
764
  fontWeight: TYPOGRAPHY.WEIGHT_MEDIUM,
694
765
  },
766
+ branchChevron: {
767
+ color: COLORS.TEXT_MUTED,
768
+ fontSize: TYPOGRAPHY.SIZE_SM,
769
+ marginLeft: SPACING.XS,
770
+ },
695
771
  statusDot: {
696
772
  width: SIZES.STATUS_DOT,
697
773
  height: SIZES.STATUS_DOT,
@@ -0,0 +1,257 @@
1
+ import React, { useState } from "react";
2
+ import {
3
+ View,
4
+ Text,
5
+ StyleSheet,
6
+ TouchableOpacity,
7
+ ScrollView,
8
+ TextInput,
9
+ } from "react-native";
10
+ import type { BranchInfo } from "../services/websocket";
11
+ import { SPACING, LAYOUT, COLORS, TYPOGRAPHY } from "../constants/design";
12
+
13
+ // Header height: paddingVertical (14) * 2 + content (~20) + border (1) ≈ 49
14
+ const HEADER_HEIGHT = 49;
15
+
16
+ interface BranchSwitcherProps {
17
+ branches: BranchInfo[];
18
+ currentBranch: string;
19
+ onSelect: (branchName: string) => void;
20
+ onCreate: (branchName: string) => void;
21
+ onClose: () => void;
22
+ error?: string | null;
23
+ }
24
+
25
+ export function BranchSwitcher({
26
+ branches,
27
+ currentBranch,
28
+ onSelect,
29
+ onCreate,
30
+ onClose,
31
+ error,
32
+ }: BranchSwitcherProps) {
33
+ const [showCreateInput, setShowCreateInput] = useState(false);
34
+ const [newBranchName, setNewBranchName] = useState("");
35
+
36
+ const handleCreate = () => {
37
+ const trimmed = newBranchName.trim();
38
+ if (trimmed) {
39
+ onCreate(trimmed);
40
+ setNewBranchName("");
41
+ setShowCreateInput(false);
42
+ }
43
+ };
44
+
45
+ return (
46
+ <View style={styles.overlay}>
47
+ <TouchableOpacity style={styles.backdrop} onPress={onClose} activeOpacity={1} />
48
+ <View style={styles.dropdown}>
49
+ {error && (
50
+ <View style={styles.errorBanner}>
51
+ <Text style={styles.errorText} numberOfLines={2}>{error}</Text>
52
+ </View>
53
+ )}
54
+ <ScrollView style={styles.branchList} bounces={false}>
55
+ {branches.map((branch, index) => (
56
+ <TouchableOpacity
57
+ key={branch.name}
58
+ style={[
59
+ styles.branchItem,
60
+ branch.isCurrent && styles.branchItemCurrent,
61
+ index === 0 && styles.branchItemFirst,
62
+ ]}
63
+ onPress={() => {
64
+ if (!branch.isCurrent) {
65
+ onSelect(branch.name);
66
+ }
67
+ }}
68
+ activeOpacity={branch.isCurrent ? 1 : 0.6}
69
+ >
70
+ <View style={styles.branchInfo}>
71
+ <Text
72
+ style={[
73
+ styles.branchName,
74
+ branch.isCurrent && styles.branchNameCurrent,
75
+ ]}
76
+ numberOfLines={1}
77
+ >
78
+ {branch.name}
79
+ </Text>
80
+ {branch.prNumber && (
81
+ <View style={styles.prBadge}>
82
+ <Text style={styles.prBadgeText}>#{branch.prNumber}</Text>
83
+ </View>
84
+ )}
85
+ </View>
86
+ {branch.isCurrent && (
87
+ <Text style={styles.currentIndicator}>✓</Text>
88
+ )}
89
+ </TouchableOpacity>
90
+ ))}
91
+ </ScrollView>
92
+
93
+ <View style={styles.createSection}>
94
+ {showCreateInput ? (
95
+ <View style={styles.createInputRow}>
96
+ <TextInput
97
+ style={styles.createInput}
98
+ value={newBranchName}
99
+ onChangeText={setNewBranchName}
100
+ placeholder="branch-name"
101
+ placeholderTextColor={COLORS.TEXT_MUTED}
102
+ autoFocus
103
+ autoCapitalize="none"
104
+ autoCorrect={false}
105
+ onSubmitEditing={handleCreate}
106
+ returnKeyType="done"
107
+ />
108
+ <TouchableOpacity
109
+ style={[
110
+ styles.createConfirmButton,
111
+ !newBranchName.trim() && styles.createConfirmDisabled,
112
+ ]}
113
+ onPress={handleCreate}
114
+ disabled={!newBranchName.trim()}
115
+ >
116
+ <Text style={styles.createConfirmText}>Create</Text>
117
+ </TouchableOpacity>
118
+ </View>
119
+ ) : (
120
+ <TouchableOpacity
121
+ style={styles.createButton}
122
+ onPress={() => setShowCreateInput(true)}
123
+ >
124
+ <Text style={styles.createButtonText}>+ New branch from main</Text>
125
+ </TouchableOpacity>
126
+ )}
127
+ </View>
128
+ </View>
129
+ </View>
130
+ );
131
+ }
132
+
133
+ const styles = StyleSheet.create({
134
+ overlay: {
135
+ ...StyleSheet.absoluteFillObject,
136
+ zIndex: 100,
137
+ },
138
+ backdrop: {
139
+ ...StyleSheet.absoluteFillObject,
140
+ backgroundColor: "rgba(0,0,0,0.3)",
141
+ },
142
+ dropdown: {
143
+ position: "absolute",
144
+ top: HEADER_HEIGHT,
145
+ left: SPACING.SM,
146
+ right: SPACING.SM,
147
+ maxHeight: "60%",
148
+ backgroundColor: "#1C1C1E",
149
+ borderRadius: LAYOUT.BORDER_RADIUS_SM,
150
+ borderWidth: 1,
151
+ borderColor: "rgba(255,255,255,0.12)",
152
+ overflow: "hidden",
153
+ },
154
+ branchList: {
155
+ maxHeight: 300,
156
+ },
157
+ branchItem: {
158
+ flexDirection: "row",
159
+ alignItems: "center",
160
+ justifyContent: "space-between",
161
+ paddingHorizontal: SPACING.LG,
162
+ paddingVertical: SPACING.MD + 2,
163
+ borderBottomWidth: StyleSheet.hairlineWidth,
164
+ borderBottomColor: "rgba(255,255,255,0.06)",
165
+ },
166
+ branchItemFirst: {
167
+ paddingTop: SPACING.MD + 2,
168
+ },
169
+ branchItemCurrent: {
170
+ backgroundColor: "rgba(255,255,255,0.06)",
171
+ },
172
+ branchInfo: {
173
+ flex: 1,
174
+ flexDirection: "row",
175
+ alignItems: "center",
176
+ gap: SPACING.SM,
177
+ },
178
+ branchName: {
179
+ color: "rgba(255,255,255,0.85)",
180
+ fontSize: TYPOGRAPHY.SIZE_MD,
181
+ fontWeight: TYPOGRAPHY.WEIGHT_NORMAL,
182
+ flexShrink: 1,
183
+ },
184
+ branchNameCurrent: {
185
+ color: COLORS.TEXT_PRIMARY,
186
+ fontWeight: TYPOGRAPHY.WEIGHT_MEDIUM,
187
+ },
188
+ prBadge: {
189
+ backgroundColor: "rgba(0,122,255,0.15)",
190
+ paddingHorizontal: SPACING.SM,
191
+ paddingVertical: 2,
192
+ borderRadius: 8,
193
+ },
194
+ prBadgeText: {
195
+ color: COLORS.STATUS_INFO,
196
+ fontSize: TYPOGRAPHY.SIZE_XS,
197
+ fontWeight: TYPOGRAPHY.WEIGHT_MEDIUM,
198
+ },
199
+ currentIndicator: {
200
+ color: COLORS.STATUS_SUCCESS,
201
+ fontSize: TYPOGRAPHY.SIZE_SM,
202
+ marginLeft: SPACING.SM,
203
+ },
204
+ createSection: {
205
+ paddingHorizontal: SPACING.LG,
206
+ paddingVertical: SPACING.MD,
207
+ borderTopWidth: StyleSheet.hairlineWidth,
208
+ borderTopColor: "rgba(255,255,255,0.08)",
209
+ },
210
+ createButton: {
211
+ paddingVertical: SPACING.XS,
212
+ },
213
+ createButtonText: {
214
+ color: COLORS.STATUS_INFO,
215
+ fontSize: TYPOGRAPHY.SIZE_MD,
216
+ fontWeight: TYPOGRAPHY.WEIGHT_MEDIUM,
217
+ },
218
+ createInputRow: {
219
+ flexDirection: "row",
220
+ alignItems: "center",
221
+ gap: SPACING.SM,
222
+ },
223
+ createInput: {
224
+ flex: 1,
225
+ backgroundColor: "rgba(255,255,255,0.08)",
226
+ color: COLORS.TEXT_PRIMARY,
227
+ fontSize: TYPOGRAPHY.SIZE_MD,
228
+ paddingHorizontal: SPACING.MD,
229
+ paddingVertical: SPACING.SM,
230
+ borderRadius: 10,
231
+ },
232
+ createConfirmButton: {
233
+ backgroundColor: COLORS.STATUS_INFO,
234
+ paddingHorizontal: SPACING.MD,
235
+ paddingVertical: SPACING.SM,
236
+ borderRadius: 10,
237
+ },
238
+ createConfirmDisabled: {
239
+ opacity: 0.4,
240
+ },
241
+ createConfirmText: {
242
+ color: COLORS.TEXT_PRIMARY,
243
+ fontSize: TYPOGRAPHY.SIZE_SM,
244
+ fontWeight: TYPOGRAPHY.WEIGHT_SEMIBOLD,
245
+ },
246
+ errorBanner: {
247
+ backgroundColor: "rgba(255,59,48,0.15)",
248
+ paddingHorizontal: SPACING.LG,
249
+ paddingVertical: SPACING.SM,
250
+ borderBottomWidth: StyleSheet.hairlineWidth,
251
+ borderBottomColor: "rgba(255,59,48,0.3)",
252
+ },
253
+ errorText: {
254
+ color: "#FF6B6B",
255
+ fontSize: TYPOGRAPHY.SIZE_SM,
256
+ },
257
+ });