Skip to content

feat: copilot cli + shells that actually source .zshrc#2

Open
megamanics wants to merge 2 commits intoAwalTerminal:mainfrom
megamanics:copilot-and-shells-that-actually-source-zshrc
Open

feat: copilot cli + shells that actually source .zshrc#2
megamanics wants to merge 2 commits intoAwalTerminal:mainfrom
megamanics:copilot-and-shells-that-actually-source-zshrc

Conversation

@megamanics
Copy link
Copy Markdown

what

two things, both small, both delivered with the kind of confidence
that only comes from finally understanding why nothing was working.

  1. github copilot cli is now a first-class model — alongside
    claude, gemini, and codex. menu reads like a streaming service.
  2. shells launch with -i -l -c instead of -l -c — so .zshrc
    actually runs and node/npm are visible to the auto-installer.
    plus binaryPath learned about directories that aren't
    /usr/local/bin.

why

before this, on a machine where claude/gemini/codex weren't already
installed, picking one from the menu would:

  1. spawn zsh -l -c "command -v claude || npm install -g … && claude"
  2. zsh skips .zshrc because it's not interactive
  3. fnm/nvm never initialize, so npm is not on PATH
  4. npm install exits with command not found
  5. && short-circuits, the shell exits, the pty closes
  6. ui shows "claude session has ended" before the user blinked

it looked like the app was broken. it was just a missing flag.

what changed

file change
core/src/io/pty.rs spawn shell with -i -l -c instead of -l -c so .zshrc runs
app/.../SessionManager.swift binaryPath checks ~/.local/bin, ~/.bun/bin, ~/bin, ~/.cargo/bin, with a cached fallback to the user's own login shell (3s timeout)
app/.../ModelCatalog.swift new Copilot entry — command copilot, install npm install -g @github/copilot, danger --allow-all, resume copilot --resume, config ~/.copilot/config.json
app/.../AIComponentInjector.swift route copilot through the AGENTS.md path (same as gemini/codex)
app/.../SessionManager.swift interactive resume entry for copilot
app/.../TerminalView+Menu.swift three loading messages because spinning up the octocat deserves billing
app/.../WindowStateStore.swift doc comment

tests

  • universal release build (arm64 + x86_64) — passes
  • cargo fmt — clean
  • manual: launched copilot session from a clean app launch on a
    machine where copilot lives in ~/.local/bin/copilot. resumed from
    the menu. did not see "session has ended" once.
  • regression: shell + plain shell paths still spawn correctly
    (the -i only applies when a command is passed)

notes

  • the danger flag for copilot is --allow-all, not --allow-all-tools.
    the latter only suppresses tool prompts; awal's danger mode contract
    is "skip everything", which is what --allow-all does (it's the
    alias for --allow-all-tools --allow-all-paths --allow-all-urls).
  • binaryPath change is a quiet bonus fix that unblocks codex/gemini
    resume entries on the same npm-managed setups, not just copilot.

we were spawning AI sessions as zsh -l -c. login but not interactive.
zsh skips .zshrc for that. fnm and nvm live in .zshrc. so node and
npm were invisible. the auto-installer for claude/gemini/codex then
ran 'npm install' against a missing npm. the shell exited. the ui
showed 'session has ended' before the user even sat down.

now we spawn -i -l -c. .zshrc runs. npm exists. installs work.

binaryPath also stopped pretending the world is two directories.
it now checks ~/.local/bin, ~/.bun/bin, ~/bin, ~/.cargo/bin, and
falls back to asking the user's own login shell where the binary is.
cached, with a 3 second leash. resume entries finally show up for
people who don't keep their tools in /usr/local/bin like it's 2014.
claude. gemini. codex. and now copilot. the menu reads like a
streaming service.

ModelCatalog gets a new entry. command 'copilot'. installs via
npm install -g @github/copilot. danger flag is --allow-all because
that's the one that actually means it. resume via copilot --resume.
config at ~/.copilot/config.json.

AIComponentInjector routes copilot through the same AGENTS.md path
gemini and codex use. SessionManager surfaces an interactive resume
entry when the binary is around. TerminalView+Menu gets three new
loading messages because spinning up the octocat deserves billing.

the model menu, status bar, llm tab bar, and resume picker all read
from ModelCatalog.all. so they pick this up without being told.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant