E.g. Python, JS/TS with node.js/deno, Lua, Bash, Powershell qualify as scripting language, but C, C++, Rust are not.
Of course there's a grey area of compilers which allow compiling and running a "script" via shebang.
A language can be designed once and then interpreters and compilers (and transpilers) can be made available for it.
Python is a classic example: it's most commonly interpreted, but can be compiled when performance matters.
C is usually compiled, but tcc offers the option to directly run it from source (-run).
History has given us both compilers and interpreters for various dialects of BASIC since the 80s.
Honestly I can't imagine why a language designer should decide upfront if the result of their study will be interpreted or compiled. And I have no idea what choices should they make to characterize it as a "scripting" language.
While strictly true, some language features are awkward or unsuitable for scripting purposes. For instance, C++ templates and Haskell's type classes with extensions that make overload resolution Turing complete. You can do this, but it seems like a poor choice where the language ostensibly has runtime evaluation and type information available, and so you don't need to so strictly stratify the types and values. This collapses effectively two programming language levels into one, and considerably simplifies quite a bit of the runtime, compiler/interpreter, and the programs that can be expressed in the language
I like Go, but to me it isn’t a scripting language like Python and Ruby because it has less ergonomic APIs for common operations (especially for strings and slices). Rather, Go prefers a literal representation of what’s going on in memory. For instance, there’s no “str1[1:5] + str2[1]” api, or you append to a slice with “s2 = append(s1, newElement)”. You can’t just “s1 + newElement”. I think Go’s reasoning is that it likes to avoid less literal features like operator overloading, and append() hints that a heap allocation might occur. But in a scripting language, you shouldn’t care that a heap allocation occurs and instead should choose a more concise and ergonomic api.
Java isn’t a scripting language because it’s so wordy.
Rust isn’t a scripting language because its type system and borrow checker are a bit too much.
Haskell isn’t a scripting language because monads and lazy execution are a bit much.
When I think of scripting languages like Python and Ruby, they focus on making common scripting type tasks easy, which often involves giving the programming less control over the machine. But at the same time, they don’t introduce any opinionated language abstractions like monads, a borrow checker, and actor threading model, etc. It also just shouldn’t be that wordy or type-heavy in a way that would slow down prototyping.
Traditional scripting languages have been dynamically types. But I think they can still be statically typed (like this language is trying to do). There isn’t a hard boundary, but once you are “too far into the weeds”, you notice that you are too far into weeds and not in scripting language territory anymore.