I think I've finally decided to declare @ to be a shorthand for "match any item at this position", and not take an argument.
This combinator's "long" form is called ONE (a replacement for historical SKIP, because reading [x: skip] and expecting that to store an item in a variable sounds like the opposite of skipping... and also, SKIP being arity-0 doesn't fit with the rest of the system... UPARSE instead has a SKIP combinator that takes how much to skip):
>> parse [#foo <bar>] [issue! one]
== <bar>
So now, it simply has a shorthand:
>> parse [#foo <bar>] [issue! @]
== <bar>
To justify why this isn't a fully arbitrary choice: when we see something like @var that's matching at the current position under the constraint of the provided variable:
>> block: [some "a"]
>> parse [[some "a"] [some "a"]] [some @block]
== [some "a"]
So it doesn't seem too crazy that when you take away the variable name that's being looked up for the constraint, you'd get a combinator that matches anything.
For Quoting, There's JUST and LITERAL
This means @ doesn't behave like it does in the main evaluator as an arity-1 operator for literalizing the subsequent argument.
But you have other options. JUST will "just" synthesize the value (don't match it), while LITERAL will match it (and synthesize if matched).
>> parse [] [just x]
== x
>> parse [''x] [literal ''x]
== ''x
LITERAL is nice when the thing you are matching has more than one quote level, because otherwise it can feel a little confusing:
>> parse [''x] ['''x]
== ''x
It's also nice if something has a quote mark in the name:
>> foo': "foo prime"
>> parse [foo'] ['foo'] ; hrrrm
== foo'
>> parse [foo'] [literal foo']
== foo'
As a shorthand, there's LIT.
>> parse [foo'] [lit foo']
== foo'