Skip to content

Fix for #168: Don't write output on SessionStart for Copilot#181

Open
maxfelker wants to merge 2 commits into
DietrichGebert:mainfrom
maxfelker:fix/issue-168-copilot-token
Open

Fix for #168: Don't write output on SessionStart for Copilot#181
maxfelker wants to merge 2 commits into
DietrichGebert:mainfrom
maxfelker:fix/issue-168-copilot-token

Conversation

@maxfelker

@maxfelker maxfelker commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

tl;dr: !isCodex was too broad — Copilot sessions leaked Claude-only content into additionalContext, breaking token validation on Windows.


What broke

ponytail-activate.js had two guards that used isCodex to skip Claude-specific behaviour. Both conditions forgot about Copilot — so Copilot sessions fell through into Claude-only paths.

Bug 1 — statusline nudge injected into Copilot context

// before
if (!isCodex) try {

The statusline nudge appends a raw JSON-like fragment to the hook output:

"statusLine": { "type": "command", "command": "powershell -ExecutionPolicy Bypass -File \"...\"" }

Copilot's parser received this inside additionalContext, tried to interpret it as a structured instruction token, and rejected it: "the token is not a valid instructions separator in this version."

The statusline is a Claude Code setting (~/.claude/settings.json). Copilot has no equivalent and should never see this nudge.

Bug 2 — off-mode emitted 'OK' to Copilot

// before
writeHookOutput('SessionStart', 'off', isCodex ? '' : 'OK');

Codex got '' → empty JSON output {}. Copilot got 'OK'{ "additionalContext": "OK" }. In off mode nothing should be injected. Same class of bug, same fix.

What changed

hooks/ponytail-activate.js only — two lines:

// import isCopilot alongside isCodex
const { clearMode, isCodex, isCopilot, setMode, writeHookOutput } = require('./ponytail-runtime');

// Bug 1: scope statusline nudge to Claude only
if (!isCodex && !isCopilot) try {

// Bug 2: off mode emits nothing for both non-Claude hosts
const hookOutput = (isCodex || isCopilot) ? '' : 'OK';
writeHookOutput('SessionStart', 'off', hookOutput);

isCopilot was already exported from ponytail-runtime.js — it just wasn't imported here.

Test

node tests/hooks.test.js — hook compatibility checks passed.


on behalf of @maxfelker — ponytail found it, two lines fixed it.

@rajpratham1 rajpratham1 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice improvement! Adding isCopilot alongside the existing isCodex checks keeps the behavior consistent across supported environments. I also like the introduction of the hookOutput variable—it makes the intent a bit clearer and avoids repeating the conditional. Overall, the changes look clean and make the logic easier to follow. LGTM!

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.

2 participants