o: support colon separator and quoted names in context arg

- session:agent works as alternative to session/agent
- Colon takes precedence (allows slashes in session names)
- Quoted arguments with spaces now work: o "my session:agent" prompt
- Removed set -- $* which broke quoted arguments
- Updated help with examples
This commit is contained in:
Levi Neely 2026-10-09 12:21:20 +02:00
parent 56f6d3c655
commit e1d01716f3
1 changed files with 34 additions and 9 deletions

View File

@ -5,8 +5,11 @@
# o <cmd> Root level # o <cmd> Root level
# o <session> <cmd> Session level # o <session> <cmd> Session level
# o <session>/<agent> <cmd> Agent level # o <session>/<agent> <cmd> Agent level
# o <session>:<agent> <cmd> Agent level (colon separator)
# #
# The slash in session/agent disambiguates context level. # The slash or colon in session/agent disambiguates context level.
# Use colon when session or agent names contain slashes.
# Names with spaces can be quoted: o "my session:my agent" prompt
# #
# Subcommands: # Subcommands:
# read <path> Read a file (-l to loop) # read <path> Read a file (-l to loop)
@ -476,8 +479,11 @@ Context is determined by the first argument:
o <cmd> Root level o <cmd> Root level
o <session> <cmd> Session level o <session> <cmd> Session level
o <session>/<agent> <cmd> Agent level o <session>/<agent> <cmd> Agent level
o <session>:<agent> <cmd> Agent level (colon separator)
The slash in <session>/<agent> disambiguates context level. The slash or colon in session/agent disambiguates context level.
Use colon when session or agent names contain slashes.
Names with spaces can be quoted: o "my session:my agent" prompt
Paths starting with / are root-relative (ignore context): Paths starting with / are root-relative (ignore context):
o myproj ls /bypass List root bypass/ even in session context o myproj ls /bypass List root bypass/ even in session context
@ -497,7 +503,7 @@ Commands (availability depends on context):
deny [id] Deny pending bypass request deny [id] Deny pending bypass request
read/write <path> Access session files read/write <path> Access session files
Agent level (o <session>/<agent> ...): Agent level (o <session>/<agent> or <session>:<agent> ...):
new [cwd] Create session (if needed) and agent new [cwd] Create session (if needed) and agent
ls List agent files ls List agent files
ctl <cmd> Agent control (stop, compact, model, etc.) ctl <cmd> Agent control (stop, compact, model, etc.)
@ -519,6 +525,8 @@ Commands (availability depends on context):
Examples: Examples:
o ls # list root (sessions, models) o ls # list root (sessions, models)
o myproj/coding new # create session+agent (cwd=$PWD) o myproj/coding new # create session+agent (cwd=$PWD)
o myproj:coding new # same, using colon separator
o "my proj:coding" new # session name with space
o myproj/coding new ~/src # create with specific cwd o myproj/coding new ~/src # create with specific cwd
o myproj ls # list session contents o myproj ls # list session contents
o myproj/coding prompt # interactive prompt o myproj/coding prompt # interactive prompt
@ -560,23 +568,40 @@ dispatch_cmd() {
} }
# Parse context from first argument # Parse context from first argument
# Supports:
# session/agent (slash separator)
# session:agent (colon separator)
# "session name/agent" (quoted with spaces)
# session\ name/agent (escaped spaces)
parse_context() { parse_context() {
local arg="$1" local arg="$1"
if [[ "$arg" == */* ]]; then
# session/agent format # Check for colon or slash separator
# Colon takes precedence if both present (allows session with / in name)
if [[ "$arg" == *:* ]]; then
CTX_SESSION="${arg%%:*}"
CTX_AGENT="${arg#*:}"
elif [[ "$arg" == */* ]]; then
CTX_SESSION="${arg%%/*}" CTX_SESSION="${arg%%/*}"
CTX_AGENT="${arg#*/}" CTX_AGENT="${arg#*/}"
PREFIX="session/$CTX_SESSION/agent/$CTX_AGENT"
else else
# session only # session only
CTX_SESSION="$arg" CTX_SESSION="$arg"
CTX_AGENT=""
fi
# Build prefix
if [[ -n "$CTX_AGENT" ]]; then
PREFIX="session/$CTX_SESSION/agent/$CTX_AGENT"
else
PREFIX="session/$CTX_SESSION" PREFIX="session/$CTX_SESSION"
fi fi
} }
# Re-split arguments: handles quoted invocations (e.g., acme passes # Note: We do NOT re-split arguments here. The previous `set -- $*` was
# the entire command as a single-quoted string). # removed because it breaks quoted arguments with spaces. If callers pass
set -- $* # a single quoted string, they should use eval or proper quoting.
# For acme integration, the calling script should handle argument parsing.
# Main dispatch # Main dispatch
if [[ $# -lt 1 ]]; then if [[ $# -lt 1 ]]; then