The Script Debugger scripts included above do not work correctly when the script being edited contains individual characters with more than one 16-bit code unit (typically emojis). The following script fixes this.
use framework "Foundation"
use scripting additions
on main()
	set commentCharacters to "# " --edit as desired
	tell application "Script Debugger" to tell document 1
		set allCode to source text
		set {cr1, cr2} to selection ASObjC range --uses 16-bit code units
		set {pr1, pr2} to getParagraphRange(allCode, cr1, cr2) of me
		set selection ASObjC range to {pr1, pr2}
		set selectedCode to selection
		set editedCode to getEditedCode(selectedCode, commentCharacters) of me
		set contents of selection to editedCode
		set selection ASObjC range to {pr1, 0}
	end tell
end main
on getParagraphRange(theString, cr1, cr2)
	set theString to current application's NSString's stringWithString:theString
	set paragraphRange to theString's paragraphRangeForRange:{cr1, cr2} --uses 16-bit code units
	return {paragraphRange's location, paragraphRange's |length|}
end getParagraphRange
on getEditedCode(theString, theCharacters)
	set theString to current application's NSMutableString's stringWithString:theString
	set removeCount to theString's replaceOccurrencesOfString:("(?m)^(\\h*)" & theCharacters) withString:"$1" options:1024 range:{0, theString's |length|()} --option 1024 is regex
	if removeCount is greater than 0 then return theString as text
	theString's replaceOccurrencesOfString:"(?m)^(\\h*\\S)" withString:(theCharacters & "$1") options:1024 range:{0, theString's |length|()}
	return theString as text
end getEditedCode
main()
This script is the same as the above except that the code selection is not removed when the script ends.
use framework "Foundation"
use scripting additions
on main()
	set commentCharacters to "# " --edit as desired
	tell application "Script Debugger" to tell document 1
		set allCode to source text
		set {cr1, cr2} to selection ASObjC range --character range of current selection
		set {pr1, pr2} to getParagraphRange(allCode, cr1, cr2) of me --paragraph range of current selection
		set selection ASObjC range to {pr1, pr2}
		set selectedCode to selection
		set {editedCode, editCount, editAction} to getEditedCode(selectedCode, commentCharacters) of me
		set contents of selection to editedCode
		set pr2 to (pr2 + ((count commentCharacters) * editCount * editAction))
		set selection ASObjC range to {pr1, pr2}
	end tell
end main
on getParagraphRange(theString, cr1, cr2)
	set theString to current application's NSString's stringWithString:theString
	set paragraphRange to theString's paragraphRangeForRange:{cr1, cr2}
	return {paragraphRange's location, paragraphRange's |length|}
end getParagraphRange
on getEditedCode(theString, theCharacters)
	set theString to current application's NSMutableString's stringWithString:theString
	set removeCount to theString's replaceOccurrencesOfString:("(?m)^(\\h*)" & theCharacters) withString:"$1" options:1024 range:{0, theString's |length|()}
	if removeCount is greater than 0 then return {theString as text, removeCount, "-1"}
	set addCount to theString's replaceOccurrencesOfString:"(?m)^(\\h*\\S)" withString:(theCharacters & "$1") options:1024 range:{0, theString's |length|()}
	return {theString as text, addCount, "1"}
end getEditedCode
main()