Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions skills/embed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,31 @@ func TestHeySkillReusesAuthenticationForUnattendedAgents(t *testing.T) {
}
}
}

func TestHeySkillRetriesMacOSKeychainAccessWithoutBroadEscalation(t *testing.T) {
data, err := FS.ReadFile("hey/SKILL.md")
if err != nil {
t.Fatal(err)
}
content := string(data)

for _, want := range []string{
"On macOS under Codex",
"retry `hey auth status --json` once with elevated sandbox permission",
"one read-only command",
"normal approval flow",
"rerun only the exact `hey` command the user requested",
"separate one-command approval",
"`data.authenticated` is `true`",
"`data.authenticated` is `false` or the status command fails",
"Never run the macOS `security` command",
"print or copy credentials",
"move credentials into a file",
"never disable the sandbox globally",
"never set `HEY_NO_KEYRING=1`",
Comment thread
robzolkos marked this conversation as resolved.
} {
if !strings.Contains(content, want) {
t.Errorf("embedded HEY skill does not contain %q", want)
}
}
}
6 changes: 4 additions & 2 deletions skills/hey/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ CLI for HEY: mailboxes, labels, collections, email threads, contacts, replies, c
**MUST follow these rules:**

1. **Choose the right structured output** — use `--jq '<expression>'` to filter or extract fields and `--json` for the full response. Never pipe to an external `jq`; `--jq` is built in and implies `--json`.
2. **Reuse stored authentication** — run the requested data command; it uses stored credentials and refreshes expiring OAuth tokens automatically. If it returns an auth error, report the task as blocked. Use `hey auth status --json` when an explicit authentication check is needed. Never run `hey auth login` unattended; use it only for interactive recovery with the user present.
2. **Reuse stored authentication** — run the requested data command; it uses stored credentials and refreshes expiring OAuth tokens automatically. If it returns an auth error, follow the one-command macOS/Codex retry in [Authentication](#authentication) before you report the task as blocked. Use `hey auth status --json` when an explicit authentication check is needed. Never run `hey auth login` unattended; use it only for interactive recovery with the user present.
3. **HTML output** is available via `--html` for commands that return HTML content
4. **Linked mail accounts share one login** — use `hey account list --json`, then `--account <id|all>` when a task must target one account
5. **Local HEY configuration requires human trust** — never run `hey config trust-local` without the user's explicit approval
Expand Down Expand Up @@ -851,7 +851,9 @@ error.

Data commands use the credentials HEY already stores and refresh expiring OAuth tokens automatically. Run the requested data command without a login preflight. Use `hey auth status --json` when the user asks for authentication status or when an explicit authentication check helps diagnose a failure; it reports whether credentials are available without changing them.

If a data command returns exit code 3 with `"code": "auth"`, report that authentication is required and the task is blocked. Tell the user to run `hey auth login`; do not run it for them unattended.
If a data command returns exit code 3 with `"code": "auth"`, authentication is unavailable to that process. On macOS under Codex, the sandbox can hide credentials that the HEY CLI stores in Keychain. Before reporting the task as blocked, use the harness's normal approval flow to retry `hey auth status --json` once with elevated sandbox permission. Limit the escalation to this one read-only command. If the response's `data.authenticated` is `true`, rerun only the exact `hey` command the user requested through a separate one-command approval. If `data.authenticated` is `false` or the status command fails, report the task as blocked and tell the user to run `hey auth login`; do not run it for them unattended.

Never run the macOS `security` command to read Keychain contents, print or copy credentials, or move credentials into a file; never disable the sandbox globally; never set `HEY_NO_KEYRING=1` as an authentication workaround.

Piped, machine-output and non-TTY commands do not prompt for sign-in. When an agent harness runs commands under a PTY, set `HEY_NONINTERACTIVE=1` so a missing login returns the same actionable auth error instead of opening an interactive prompt.

Expand Down
Loading