Dota 1: 2070

If dagger was ground targeted it will first choose point in 2100 range from Spectre:
Spoiler: 

function Func3450 takes nothing returns nothing
local unit loc_unit01=GetTriggerUnit()
local unit loc_unit02=GetSpellTargetUnit()
local real loc_real01=Func0125(GetUnitX(loc_unit01))
local real loc_real02=Func0128(GetUnitY(loc_unit01))
local unit loc_unit03=CreateUnit(GetOwningPlayer(loc_unit01), ('h003'),loc_real01,loc_real02,0)
local timer loc_timer01=CreateTimer()
local integer loc_integer01=GetHandleId(loc_timer01)
local group loc_group01=Func0030()
local location loc_location01
local real loc_real03
local real loc_real04
local real loc_real05
call SetUnitPathing(loc_unit03,false)
call SaveGroupHandle(hashtable001,(loc_integer01),(133) ,(loc_group01))
call SaveUnitHandle(hashtable001,(loc_integer01),(14),( loc_unit01))
call SaveUnitHandle(hashtable001,(loc_integer01),(45),( loc_unit03))
if loc_unit02!=null then
call SaveInteger(hashtable001,(loc_integer01),(30),(Fun c0024(loc_unit02)))
call TimerStart(loc_timer01,0.035,true,function Func3445)
else
set loc_location01=GetSpellTargetLoc()
set loc_real04=GetLocationX(loc_location01)
set loc_real05=GetLocationY(loc_location01)
set loc_real03=Atan2(loc_real05-loc_real02,loc_real04-loc_real01)
call SetUnitFacing(loc_unit03,loc_real03*bj_RADTODEG)
set loc_real04=Func0125(loc_real01+2100*Cos(loc_real03 ))
set loc_real05=Func0128(loc_real02+2100*Sin(loc_real03 ))

call SaveReal(hashtable001,(loc_integer01),(47),((loc_r eal04)*1.0))
call SaveReal(hashtable001,(loc_integer01),(48),((loc_r eal05)*1.0))
call SaveReal(hashtable001,(loc_integer01),(13),((loc_r eal03)*1.0))
call TimerStart(loc_timer01,0.035,true,function Func3446)
endif
set loc_timer01=CreateTimer()
set loc_integer01=GetHandleId(loc_timer01)
call SetUnitPathing(loc_unit01,false)
call SaveUnitHandle(hashtable001,(loc_integer01),(14),( loc_unit01))
call TimerStart(loc_timer01,0.2,true,function Func3448)
endfunction

The function will terminate then it comes in 40 range
Spoiler: 

function Func3446 takes nothing returns nothing
local timer loc_timer01=GetExpiredTimer()
local integer loc_integer01=GetHandleId(loc_timer01)
local group loc_group01=(LoadGroupHandle(hashtable001,(loc_int eger01),(133)))
local group loc_group02=Func0030()
local boolexpr loc_boolexpr01=Condition(function Func3444)
local unit loc_unit01=(LoadUnitHandle(hashtable001,(loc_integ er01),(14)))
local unit loc_unit02=(LoadUnitHandle(hashtable001,(loc_integ er01),(45)))
local real loc_real01=(LoadReal(hashtable001,(loc_integer01), (47)))
local real loc_real02=(LoadReal(hashtable001,(loc_integer01), (48)))
local real loc_real03=GetUnitX(loc_unit02)
local real loc_real04=GetUnitY(loc_unit02)
local real loc_real05=(LoadReal(hashtable001,(loc_integer01), (13)))
local real loc_real06=Func0125(GetUnitX(loc_unit02)+30*Cos(lo c_real05))
local real loc_real07=Func0128(GetUnitY(loc_unit02)+30*Sin(lo c_real05))
local unit loc_unit03
local integer loc_integer02=GetUnitAbilityLevel(loc_unit01,('A0H W'))
if(LoadBoolean(hashtable001,(loc_integer01),(384)) )then
call SaveBoolean(hashtable001,(loc_integer01),(384),(fa lse))
set loc_unit03=CreateUnit(GetOwningPlayer(loc_unit01), ('h002'),loc_real03,loc_real04,0)
call SetUnitAbilityLevel(loc_unit03,('A0I2'),loc_intege r02)
call SetUnitAbilityLevel(loc_unit03,('A0HY'),loc_intege r02)
call UnitApplyTimedLife(loc_unit03,'BTLF',12)
else
call SaveBoolean(hashtable001,(loc_integer01),(384),(tr ue))
endif
call SetUnitX(loc_unit02,loc_real06)
call SetUnitY(loc_unit02,loc_real07)
set group001=loc_group01
set unit002=loc_unit01
set real002=50*GetUnitAbilityLevel(loc_unit01,('A0HW') )
call GroupEnumUnitsInRange(loc_group02,loc_real06,loc_r eal07,150,loc_boolexpr01)
call ForGroup(loc_group02,function Func3443)
call Func0029(loc_group02)
if(loc_real06-loc_real01)*(loc_real06-loc_real01)+(loc_real07-loc_real02)*(loc_real07-loc_real02)<1600 then
call PauseTimer(loc_timer01)
call FlushChildHashtable(hashtable001,(loc_integer01))
call KillUnit(loc_unit02)
call Func0029(loc_group01)

endif
endfunction

With the step of 30 unit last function AoE check will happen at 2070

Spectral dagger limit is is 2070+150=2220



Dota 2: 2000

Travel range is same as cast range: 2000

Spectral dagger limit is is 2149=2000(travel range)+125(center-collision AoE)+24(collision)