A couple suggestions for $zip

1. The 'o' switch shouldn't be required when the export location exists as a foldername, but rather should be required only for overwriting actual files, which shouldn't include the dir-name entry inside the zip. This makes it impossible to unzip into an existing folder without using the 'o' switch, putting yourself at risk of overwriting an actual file. The error message in this case is confusing, as it's not invalid parameters just like it's not invalid parameters when /copy doesn't use -o when the output already exists.

2. Have a switch or .prop which reveals the contents of the zip to a script. Since $zip is possibly interacting with zips created with 7zip or other utilities, it's likely someone would receive a .zip via DCC which has unknown contents. This snippet is just a quick attempt to read the contents of a zip, so it won't work on all .zip files. For example it doesn't attempt to read the filesize of a zip64 format holding files whose original size is larger than 4gb, and it won't touch a zip which has a non-zero length comment at the very end of the file. It saves info to a hashtable, as well as creating a tab-delimited output as the /return value from calling this as an identifier.
; Syntax $ziplist(zipname,hashtablename)
; deletes then replaces hashtable, creates items 1+ containing. returns tab-delimited list of files
; hashtable format: counter_integer filesize|DIR filename
ziplist {
  var %size $file($1).size , %list , %ptr 1 , %counter 0 , %totsize 0
  if (%size !isnum 100-) { var %err Invalid zip | goto fail }
  bread $qt($1) $calc(%size -6) 6 &maroon.ziplist
  var %comlen $bvar(&maroon.ziplist,5).word , %cdirloc $bvar(&maroon.ziplist,1).long
  if (%comlen != 0) { var %err non-zero comment | goto fail }
  var %cdirsize $calc(%size - %cdirloc -6)
  if (%cdirsize !isnum 5-65536) { var %err invalid central dir | goto fail }
  bread $qt($1) $calc(%cdirloc) $calc(%cdirsize +7) &maroon.ziplist
  if ($bvar(&maroon.ziplist,0) != $calc(%cdirsize +6)) { var %err invalid zip | goto fail }
  while ($bvar(&maroon.ziplist,%ptr).long == 33639248) {
    var %modtime $base($bvar(&maroon.ziplist,$calc(%ptr +12)).word,10,16,4)
    var %moddate $base($bvar(&maroon.ziplist,$calc(%ptr +14)).word,10,16,4)
    var %crc     $base($bvar(&maroon.ziplist,$calc(%ptr +16)).long,10,16,8)
    var %arcsize $bvar(&maroon.ziplist,$calc(%ptr +20)).long
    var %orisize $bvar(&maroon.ziplist,$calc(%ptr +24)).long
    var %fnamlen $bvar(&maroon.ziplist,$calc(%ptr +28)).word
    var %xtralen $bvar(&maroon.ziplist,$calc(%ptr +30)).word
    var %comtlen $bvar(&maroon.ziplist,$calc(%ptr +32)).word
    var %intattr $bvar(&maroon.ziplist,$calc(%ptr +36)).word
    var %extattr $bvar(&maroon.ziplist,$calc(%ptr +38)).long
    inc %totsize %orisize
    inc %counter | if (%counter == 1) { hfree -w $2 | hmake $2 | echo -s $ $+ ziplist contents listing of $1 }
    hadd $2 %counter $iif($isbit(%extattr,5),DIR,%orisize) $bvar(&maroon.ziplist,$calc(%ptr + 46),%fnamlen).text
    if (!$isbit(%extattr,5)) var %list $addtok(%list,$bvar(&maroon.ziplist,$calc(%ptr + 46),%fnamlen).text,9)
    inc %ptr $calc(46+ %fnamlen + %xtralen + %comtlen)
  if (%counter == 0) { var %err no contents found | goto fail }
  echo -sc info2 *ziplist %counter items for total size %totsize found in $1 and listed in hashtable $2
  return %list
  :fail | echo -sc info2 *$ziplist error: %err syntax: $ $+ ziplist(zipname,hashtable) | halt