Skip to content

Commit 596d110

Browse files
committed
fix(measure): increase sendWait timeout to 5 minutes
The measure() function was failing with "Measurement failed: {}" because sendWait has a default 1 second timeout. User interaction for screen measurement needs much longer, so increased to 5 minutes. Also updated the default hint to clarify Enter is needed to confirm.
1 parent 00bb777 commit 596d110

1 file changed

Lines changed: 231 additions & 11 deletions

File tree

src/target/app.ts

Lines changed: 231 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -467,14 +467,7 @@ export let inspectPromptPromises = () => {
467467
}
468468

469469
let runAction = async (data: AppMessage) => {
470-
// console.log(`[SDK] runAction called with:`, {
471-
// channel: data?.channel,
472-
// actionName: data?.state?.action?.name,
473-
// actionFlag: data?.state?.action?.flag,
474-
// actionValue: data?.state?.action?.value,
475-
// shortcut: data?.state?.shortcut,
476-
// mapKeys: Array.from(global.__kitActionsMap.keys())
477-
// })
470+
global.log(`[SDK] runAction called with: channel=${data?.channel}, shortcut=${data?.state?.shortcut}, input=${data?.state?.input}, focused.name=${data?.state?.focused?.name}, focused.value=${data?.state?.focused?.value}, mapKeys=${Array.from(global.__kitActionsMap.keys()).join(',')}`)
478471

479472
let action: Action | Shortcut
480473
// Try multiple ways to find the action
@@ -487,7 +480,7 @@ let runAction = async (data: AppMessage) => {
487480
for (const key of possibleKeys) {
488481
if (global.__kitActionsMap.has(key)) {
489482
action = global.__kitActionsMap.get(key)
490-
// console.log(`[SDK] Found action with key: ${key}`)
483+
global.log(`[SDK] Found action with key: ${key}`)
491484
break
492485
}
493486
}
@@ -502,26 +495,28 @@ let runAction = async (data: AppMessage) => {
502495
value?.key === data.state.shortcut
503496
) {
504497
action = value
505-
// console.log(`[SDK] Found action by shortcut: ${data.state.shortcut}`)
498+
global.log(`[SDK] Found action by shortcut: ${data.state.shortcut}, actionName=${(action as any)?.name}`)
506499
break
507500
}
508501
}
509502
}
510503

511504
if (!action) {
512-
// console.log(`[SDK] No action found for:`, data?.state)
505+
global.log(`[SDK] No action found for shortcut: ${data?.state?.shortcut}`)
513506
}
514507

515508
if (action) {
516509
const hasOnAction =
517510
typeof (action as Action)?.onAction === "function"
518511
const hasOnPress =
519512
typeof (action as Shortcut)?.onPress === "function"
513+
global.log(`[SDK] Action found: name=${(action as any)?.name}, hasOnAction=${hasOnAction}, hasOnPress=${hasOnPress}`)
520514
if (
521515
action?.value &&
522516
!hasOnAction &&
523517
!hasOnPress
524518
) {
519+
global.log(`[SDK] Submitting action value: ${action.value}`)
525520
submit(action.value)
526521
return
527522
}
@@ -532,6 +527,7 @@ let runAction = async (data: AppMessage) => {
532527
? (action as Shortcut).onPress
533528
: null
534529
if (actionFunction) {
530+
global.log(`[SDK] Calling action function for: ${(action as any)?.name}`)
535531
return await actionFunction(
536532
data?.state?.input,
537533
data?.state
@@ -3564,3 +3560,227 @@ global.notify = async options => {
35643560
}
35653561
await sendWait(Channel.NOTIFY, options)
35663562
}
3563+
3564+
// Measure - Screen area measurement tool
3565+
global.measure = async (options = {}) => {
3566+
const defaultOptions = {
3567+
color: '#00ff00',
3568+
strokeWidth: 2,
3569+
fillOpacity: 0.1,
3570+
showDimensions: true,
3571+
showCrosshair: true,
3572+
fontSize: 14,
3573+
gridSnap: 1,
3574+
constrainToDisplay: false,
3575+
allowKeyboardAdjust: true,
3576+
hint: 'Click and drag to measure an area. Press Enter to confirm, Escape to cancel.',
3577+
clipboardFormat: 'dimensions'
3578+
}
3579+
3580+
const mergedOptions = { ...defaultOptions, ...options }
3581+
3582+
try {
3583+
// Use a long timeout (5 minutes) since measurement requires user interaction
3584+
// The default 1 second timeout was causing the measurement to fail
3585+
const FIVE_MINUTES = 5 * 60 * 1000
3586+
const result = await global.sendWait(Channel.MEASURE, mergedOptions, FIVE_MINUTES)
3587+
3588+
if (result && typeof result === 'object' && !result.cancelled) {
3589+
return {
3590+
...result,
3591+
right: result.x + result.width,
3592+
bottom: result.y + result.height,
3593+
centerX: result.x + Math.floor(result.width / 2),
3594+
centerY: result.y + Math.floor(result.height / 2),
3595+
area: result.width * result.height,
3596+
cancelled: false
3597+
}
3598+
}
3599+
3600+
return null
3601+
} catch (error) {
3602+
console.error('Measurement failed:', error)
3603+
return null
3604+
}
3605+
}
3606+
3607+
// Screen Recording - Capture screen video
3608+
global.getScreenSources = async () => {
3609+
try {
3610+
const sources = await global.sendWait(Channel.GET_SCREEN_SOURCES, {})
3611+
return sources || []
3612+
} catch (error) {
3613+
console.error('Failed to get screen sources:', error)
3614+
return []
3615+
}
3616+
}
3617+
3618+
global.screenRecord = async (options = {}) => {
3619+
const defaultOptions = {
3620+
format: 'webm',
3621+
quality: 0.9,
3622+
frameRate: 30,
3623+
includeAudio: false,
3624+
selectArea: false,
3625+
showControls: true,
3626+
countdown: true,
3627+
countdownSeconds: 3,
3628+
maxDuration: 0,
3629+
hint: 'Click and drag to select recording area. Press Escape to cancel.'
3630+
}
3631+
3632+
const mergedOptions = { ...defaultOptions, ...options }
3633+
3634+
try {
3635+
let sourceId = mergedOptions.sourceId
3636+
3637+
if (!sourceId) {
3638+
const sources = await global.getScreenSources()
3639+
3640+
if (sources.length === 0) {
3641+
console.error('No screen sources available')
3642+
return null
3643+
}
3644+
3645+
if (sources.length === 1) {
3646+
sourceId = sources[0].id
3647+
} else {
3648+
sourceId = await global.arg({
3649+
placeholder: 'Select screen to record',
3650+
hint: 'Choose which display to record'
3651+
}, sources.map(s => ({
3652+
name: s.name,
3653+
value: s.id,
3654+
img: s.thumbnail
3655+
})))
3656+
3657+
if (!sourceId) {
3658+
return null
3659+
}
3660+
}
3661+
}
3662+
3663+
let area = mergedOptions.area
3664+
3665+
if (mergedOptions.selectArea && !area) {
3666+
const measureResult = await global.measure({
3667+
hint: mergedOptions.hint,
3668+
color: '#ff0000',
3669+
showDimensions: true
3670+
})
3671+
3672+
if (!measureResult) {
3673+
return null
3674+
}
3675+
3676+
area = {
3677+
x: measureResult.x,
3678+
y: measureResult.y,
3679+
width: measureResult.width,
3680+
height: measureResult.height,
3681+
displayId: measureResult.displayId ? parseInt(measureResult.displayId) : undefined
3682+
}
3683+
}
3684+
3685+
const startResult = await global.sendWait(Channel.START_SCREEN_RECORDING, {
3686+
sourceId,
3687+
area,
3688+
options: {
3689+
format: mergedOptions.format,
3690+
quality: mergedOptions.quality,
3691+
frameRate: mergedOptions.frameRate,
3692+
includeAudio: mergedOptions.includeAudio,
3693+
filePath: mergedOptions.filePath,
3694+
maxDuration: mergedOptions.maxDuration,
3695+
showControls: mergedOptions.showControls,
3696+
countdown: mergedOptions.countdown,
3697+
countdownSeconds: mergedOptions.countdownSeconds
3698+
}
3699+
})
3700+
3701+
if (!startResult || !startResult.success) {
3702+
console.error('Failed to start recording:', startResult?.error)
3703+
return null
3704+
}
3705+
3706+
const result = await global.sendWait(Channel.SCREEN_RECORDING_STATUS, {
3707+
waitForComplete: true
3708+
})
3709+
3710+
if (!result || result.cancelled) {
3711+
return null
3712+
}
3713+
3714+
return {
3715+
filePath: result.filePath,
3716+
duration: result.duration || 0,
3717+
width: area?.width || result.width || 0,
3718+
height: area?.height || result.height || 0,
3719+
cancelled: false
3720+
}
3721+
} catch (error) {
3722+
console.error('Screen recording failed:', error)
3723+
return null
3724+
}
3725+
}
3726+
3727+
global.stopScreenRecording = async () => {
3728+
try {
3729+
const result = await global.sendWait(Channel.STOP_SCREEN_RECORDING, {})
3730+
3731+
if (!result || !result.success) {
3732+
return null
3733+
}
3734+
3735+
return {
3736+
filePath: result.filePath,
3737+
duration: result.duration || 0,
3738+
width: result.width || 0,
3739+
height: result.height || 0,
3740+
cancelled: false
3741+
}
3742+
} catch (error) {
3743+
console.error('Failed to stop recording:', error)
3744+
return null
3745+
}
3746+
}
3747+
3748+
global.pauseScreenRecording = async () => {
3749+
try {
3750+
const result = await global.sendWait(Channel.PAUSE_SCREEN_RECORDING, {})
3751+
return result?.success ?? false
3752+
} catch (error) {
3753+
console.error('Failed to pause recording:', error)
3754+
return false
3755+
}
3756+
}
3757+
3758+
global.resumeScreenRecording = async () => {
3759+
try {
3760+
const result = await global.sendWait(Channel.RESUME_SCREEN_RECORDING, {})
3761+
return result?.success ?? false
3762+
} catch (error) {
3763+
console.error('Failed to resume recording:', error)
3764+
return false
3765+
}
3766+
}
3767+
3768+
global.getScreenRecordingStatus = async () => {
3769+
try {
3770+
const result = await global.sendWait(Channel.SCREEN_RECORDING_STATUS, {})
3771+
return {
3772+
isRecording: result?.status === 'recording',
3773+
isPaused: result?.status === 'paused',
3774+
duration: result?.duration || 0,
3775+
status: result?.status || 'idle'
3776+
}
3777+
} catch (error) {
3778+
console.error('Failed to get recording status:', error)
3779+
return {
3780+
isRecording: false,
3781+
isPaused: false,
3782+
duration: 0,
3783+
status: 'idle'
3784+
}
3785+
}
3786+
}

0 commit comments

Comments
 (0)