Aside probe always reports ASIDE_NOT_RUNNING under zsh: unquoted $_T timeout wrapper is never word-split
- Dominant language
- TypeScript
- Stars
- 133k
- Forks
- 19.9k
- Avg merge
- 18h 46m
- Merged PRs (30d)
- 26
Description
## Summary
The `BROWSER SETUP (Aside)` probe reports `ASIDE_NOT_RUNNING` on every run under zsh, even when Aside is installed, running, signed in, and answering `aside repl` in about a second. Every browsing skill therefore silently falls back to the bundled headless Chromium and loses the user's real sessions, which is the whole point of the Aside path.
Under bash the same snippet works. macOS ships zsh as the default login shell, and agent harnesses commonly run their shell tool as zsh, so this likely affects a large share of macOS users.
## Environment
- gstack 1.84.1.0 (global git install)
- zsh 5.9, macOS 26.6.2 (arm64)
- Aside app 1.0.825.1, Aside CLI 1.26.906.1630
- `gtimeout` present (coreutils via Homebrew)
## Cause
`scripts/resolvers/aside.ts` lines 77-81 build the timeout wrapper as a string and then use it unquoted as a command prefix:
```sh
_T=""; command -v gtimeout >/dev/null 2>&1 && _T="gtimeout 30"; ...
elif $_T aside repl 'console.log("ASIDE_READY " + pwd)' 2>&1 | grep -q '^ASIDE_READY'; then
```
zsh does not perform word splitting on unquoted parameter expansions (`SH_WORD_SPLIT` is off by default). So `$_T` expands to a single word and zsh tries to execute a command whose name is literally `gtimeout 30`. That fails with `command not found`, the `elif` branch is false, and control falls through to the `else` that prints `ASIDE_NOT_RUNNING`.
The same applies to the `timeout 30` and `perl -e alarm(shift);exec(@ARGV) 30` variants.
## Reproduce
```sh
zsh -c '
_T=""; command -v gtimeout >/dev/null 2>&1 && _T="gtimeout 30"
$_T echo hello
'
# zsh: command not found: gtimeout 30
```
Full probe on a healthy install:
```
$ aside --version
1.26.906.1630
$ aside repl 'console.log("ASIDE_READY " + pwd)'
ASIDE_READY /Users//.aside/u/0/sessions/2026-09-10_Sx4tPfkzHidQY7cz
[ok | 24ms] # 1.25s wall clock
$
ASIDE_NOT_RUNNING # expected READY
$
READY: aside 1.26.906.1630
```
## Blast radius
The snippet is generated from one template into 20 skills' `SKILL.md`:
`benchmark canary browse design-review cso design-consultation devex-review qa-only review land-and-deploy office-hours plan-eng-review plan-ceo-review investigate qa scrape plan-devex-review setup-deploy ship spec`
The failure is silent and misleading. The skill follows step 2 of the probe contract, asks the user to open Aside, re-runs, gets the same result, then quotes `ASIDE_NOT_RUNNING` and proceeds on the fallback. Nothing points at the shell, so it reads as a broken Aside install.
## Suggested fix
`${=_T}` fixes zsh but is a syntax error in bash. A shell function keeps it portable across both:
```sh
if command -v gtimeout >/dev/null 2>&1; then _t() { gtimeout 30 "$@"; }
elif command -v timeout >/dev/null 2>&1; then _t() { timeout 30 "$@"; }
elif command -v perl >/dev/null 2>&1; then _t() { perl -e 'alarm(shift); exec(@ARGV)' 30 "$@"; }
else _t() { "$@"; }
fi
if [ "${GSTACK_SKIP_ASIDE:-}" = "1" ] || ! command -v aside >/dev/null 2>&1; then
echo "NEEDS_ASIDE"
elif _t aside repl 'console.log("ASIDE_READY " + pwd)' 2>&1 | grep -q '^ASIDE_READY'; then
echo "READY: aside $(aside --version 2>/dev/null)"
else
echo "ASIDE_NOT_RUNNING"
fi
```
Worth grepping the rest of the codebase for the same `$VAR` as command-prefix pattern; any other snippet built for bash and executed under zsh has the same failure mode.
Contributor guide
Research direction
Start in scripts/resolvers/aside.ts around lines 77-81 and reproduce the reported command-prefix behavior in zsh and bash. Trace how this template generates the 20 listed SKILL.md files, then verify the Aside probe succeeds under both shells and still reports the expected fallback when Aside is unavailable. Done means the timeout handling is portable and the generated snippets no longer report ASIDE_NOT_RUNNING for a healthy install.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- bash, typescript, zsh
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100