hey について
heyスキルは、エージェントがHEY CLIでメール、連絡先、カレンダー項目などを扱う手順を示します。コマンドヘルプの確認、IDの適切な扱い、出力形式の選択、認証と送信の安全対策を重視します。
主な機能
- 01コマンド別ヘルプの確認
- 02メール、連絡先、カレンダーの操作
- 03構造化出力とフィルタリング
- 04IDとページネーションの安全策
- 05送信と認証のルール
活用シーン
- 01作業に適したHEYコマンドを探す
- 02メールスレッドを読んで整理する
- 03カレンダー項目を作成または確認する
- 04送信時の安全策に沿ってメールを作成する
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ basecamp/ skills --skill heyインストール後、Claude Code で/heyを入力して読み込まれたか確認します。
詳細
/hey - HEY メールワークフローコマンド
HEY 用の CLI です。メールボックス、ラベル、コレクション、メールスレッド、連絡先、返信、メール作成、カレンダー、ToDo、習慣、時間管理、ジャーナルエントリーを操作できます。
コマンドのリファレンスとして、インストール済みの CLI を使用してください。このスキルには、複数のコマンドにまたがるルールを記載しています。コマンドカタログは複製していません。バイナリに組み込まれたヘルプが信頼できる情報源であり、実行中のバージョンと常に一致するためです。
発見を優先するワークフロー
各タスクでは、次の手順に従ってください。
-
ユーザーの言葉から、最も深い階層にある妥当なリーフコマンドを推測します。
-
この会話内のツールの結果で引数とフラグがすでに確認されている場合を除き、実行前にそのリーフのヘルプを確認します。
hey <group> <subcommand> --agent --help -
リーフが存在しない場合は、最も近い親グループのヘルプを確認します。トップレベルのグループ自体が不明な場合に限り、ルートのヘルプを使用します。
hey <group> --agent --help # fallback hey --agent --help # last resort hey commands --json # every command with its agent_notes -
リーフの
short、long、agent_notes、flagsを信頼できる情報源として扱います。位置引数、フラグ、受け付ける値、上限を推測しないでください。 -
明示的な出力モードを指定して実行し、次の対応を決める前に構造化されたエラーを確認します。
リーフのヘルプを確認するコストは低い一方、ルートのヘルプと hey commands --json はカタログ全体を出力するため、コストがかかります。グローバルフラグ(--json、--jq、--quiet、--account、--stats)は、コマンドが対応している場合に使用できます。
必ず守るルール
- 適切な構造化出力を選択します。 フィールドの絞り込みや抽出には
--jq '<expression>'を、レスポンス全体の取得には--jsonを使用します。外部のjqにパイプしないでください。--jqは組み込み機能であり、指定すると--jsonも有効になります。 - 保存済みの認証情報を再利用します。 要求されたデータコマンドを実行すると、保存済みの認証情報が使用され、有効期限が近い OAuth トークンは自動更新されます。認証エラーが返された場合は、タスクがブロックされたと報告する前に、認証の再試行手順に従ってください。明示的に認証状態を確認する必要がある場合は、
hey auth status --jsonを使用します(保存済みの認証情報を報告し、HEY には接続しません)。ユーザーが同席している状態での対話的な復旧に限り、hey auth loginを使用してください。無人で実行してはいけません。 - リンクされたメールアカウントは、同じログインを共有します。
hey account list --jsonを使用し、特定のアカウントを対象にする必要がある場合は--account <id|all>を指定してください。 - ローカルの HEY 設定には、人による信頼の承認が必要です。 ユーザーから明示的な承認を得ずに
hey config trust-localを実行してはいけません。 not_deliveredで失敗した送信を再送信してはいけません。 送信を参照してください。- ボックス内のアイテムを変更する場合は確認してください。 IDを参照してください。HEY は一致するものがなかった場合、その ID を報告しません。
出力
--jq は JSON の成功レスポンス全体をフィルタリングするため、結果データは .data にあります。文字列の結果はプレーンテキストで出力され、オブジェクトと配列は整形された JSON として出力されます。式を結果データに直接適用する場合は、--quiet --jq を使用します。エラーは構造化されたレスポンス全体を保持します。独自の未加工出力を持つコマンド(auth token、shell-completion generate、setup、skill、tui、--version、および --output を指定しない timetrack export)では、--jq は拒否されます。hey watch は、レスポンス全体を含まない未加工の JSON イベントを1行につき1つ出力し、--jq は適用しません。
hey box list --jq '.data[] | {id, name}'
hey search "quarterly planning" --jq '.data[].topic_id'
hey box list --quiet --jq '.[].name'
- 結果が空の場合は
nullではなく空の配列になるため、何も見つからなかった一覧に対しても.data[]を安全に使用できます。 - HEY の回答に含まれないフィールドは、推測で補わず省略されます。投稿の
seenは true の場合にのみ存在するため、未読かどうかは.seen != trueで判定します。 --ids-onlyは1行につき1つの ID を出力し、--countは数字のみを出力します。これらは一覧に対して機能します。対象は、すべてのlistコマンド、スレッド一覧、hey workflow view、hey search、hey screener history、hey event day|week、hey timetrack categories、hey attachment list、hey thread read(本文を含めず、インデックスから読み取ったエントリー)です。どちらも読み取った範囲に対する結果を返します。つまり、--allまたは--limitで追加のページを読み取らない限り、最初のページが対象です。また、すべての一覧が追加ページの存在を通知するわけではありません。例外はhey screener list --countで、キュー全体の件数を数えます。スレッド一覧では、ボックス、ラベル、連絡先ではなく、投稿の件数を数えます。--allはページ数の上限に達すると停止します。上限は各一覧のヘルプに記載されています。上限に達した読み取りでは、次に続ける場所が示されます。hey box viewのようなカーソル方式の一覧ではnext_page、hey searchやhey contact listのようなページ番号方式の一覧では--pageの値を示すnoticeが表示されます。一覧が完了したと見なさず、そこから続けてください。--htmlはhey thread read、hey journal read、および連絡先の非公開メモの元の HTML をパイプまたはファイルに書き込みます。端末への出力は拒否されます。
ID
各メールスレッドには2つのIDがあります。idはボックスアイテムID(あるボックス内の1つの投稿)、topic_idはスレッドIDです。スレッド一覧の各投稿には、id、topic_id、kind(バンドル行の場合はbundle)、name(件名)、created_at、app_urlがあります。スレッド行にはさらに、contacts、summary、visible_entry_countがあります。
- ボックスアイテムID(
id):hey seen、unseen、move、label add|remove|create、trash、spam、ignore、stop-ignoring、bubble up|pop、set-aside group、bulk-reply、bundle viewで使用します。 - スレッドID(
topic_id):hey thread read|update、share、unshare、attachment list、reply、forward、compose --thread-id、collection add|remove、workflow add|move|removeで使用します。 - エントリーID:
hey thread readで取得したエントリーのidです。hey clip createに渡す場合、その引用箇所が該当メッセージの本文に含まれている必要があります。 hey contact listまたは連絡先データから取得する連絡先ID、hey screener listから取得するクリアランスID(スレッドのtopic_idも表示されるため、判断する前にそのスレッドを読む必要があります)、hey box listから取得するボックスID、hey label listから取得するラベルIDがあります。種類の異なるIDを代用したり、連絡先IDの代わりにメールアドレスを使ったりしないでください。
スレッド一覧(hey box view、label view、collection view、bundle view、contact threads、search)には両方のIDが含まれますが、例外が2つあります。バンドル行ではtopic_idが省略されることがあり、スレッドのボックスアイテムがない検索結果ではidが省略されます。
誤った種類のIDを渡しても、適切なIDに振り替えられることはありません。一致しないIDは報告されません。HEYは、呼び出し内に自分のボックスアイテムIDが少なくとも1つ含まれているかだけを確認し、一致するものすべてを変更します。hey trash、spam、label add|remove|create、bubble up|popは、一致するものが1つもない場合にのみnot_foundを返します。hey seen、unseen、move、ignore、stop-ignoring、set-aside group create|add|removeはIDを確認しません(group createでは、一致するIDがなくても空のグループが作成されます)。そのため、混在した一括処理は一部のみ成功しても全件成功として報告され、入力ミスは黙って無視されます。また、たまたまボックスアイテムIDと同じ値のtopic_idを渡すと、無関係なスレッドが操作されます。同様に、hey thread readにボックスアイテムIDを渡すと、無関係なスレッドを読んでしまうことがあります。応答を鵜呑みにせず、確認してください。
hey box view imbox --json --all --jq '{notice, next_page: .data.next_page, match: [.data.postings[] | select(.id == 12345) | {id, topic_id, seen}]}'
マークの場合は確認するか、移動の場合は移動先のボックスを読んでください。next_pageが設定されたままmatchが空の場合、ボックスが--allで読み込める範囲より大きいことを示しています。一致しないと判断するのではなく、--page <next_page>で続きを取得してください。
バンドル行。 kindがbundleの投稿は、1人の送信者からのメールを1行にまとめて表示し、スレッドではなく送信者の名前を示します。未読スレッドがちょうど1つの場合に限り、topic_idが含まれます。バンドル行のidをhey thread readに渡さないでください。hey bundle view <id>では、未読スレッドとそのtopic_idが一覧表示されます。hey contact threads <contact_id>では、その送信者とのすべてのスレッドが既読・未読を問わず一覧表示されます。バンドル内のメールが既読になった後に一覧表示されるのはここだけです。hey contact bundle|unbundle <contact_id>でグループ化を変更します。
送信
- 送信(
compose、reply、forward、draft send)では、新しいメッセージのidと、そのメッセージが属するスレッドのtopic_idが返されます。hey thread read <topic_id>で読み取ってください。 delayed: trueは、送信取り消し機能がまだ送信を保留していることを意味します。HEY は送信されるまでスレッドに表示しません。hey thread readではそのメッセージがない状態のスレッドが表示され、メッセージがスレッドを開始した場合はnot_foundが返されます。送信が失われたと判断せず、待ってから再度読み取ってください。- HEY が送信を拒否した場合(通常はアカウントの送信上限に達した場合)、
not_delivered(終了コード 7)で失敗します。HEY はエラー内のdraft_idで示される名前の下書きとしてメッセージを保持します。後でhey draft send <draft_id>を実行して送信してください。メッセージを再送信しないでください。2つ目の下書きが作成されてしまいます。 - 送信前に相手に確認してもらうには、
composeまたはreplyに--draftを追加してください。応答にはhey draft show|edit|send|deleteで操作できる下書き ID が含まれます。相手は任意の HEY アプリで確認して送信できます。または、後でhey draft sendを使って送信できます。 hey bulk-reply:sendの前にpreviewを実行してください。誤って送信した配信は、取り消し可能な時間内であればhey bulk-reply undo <delivery_id>で取り消せます。
コンテンツの作成
メッセージ本文、下書き、ジャーナルエントリー、スニペット、連絡先メモは、(-m、--content、--note、位置引数のコンテンツ、stdin、$EDITOR のいずれも)デフォルトで Markdown であり、送信時にリッチテキストに変換されます。クリップした文章、イベントメモ、時間記録メモはプレーンテキストです。各 Markdown フラグには HTML 用の対になるフラグ(--message-html、--note-html、--content-html など)があり、生の HTML に対応します。それぞれの組み合わせは相互排他的です。フェンス付きコードブロックの言語指定は、HEY がハイライト表示に対応する言語(Ruby、Python、JavaScript、TypeScript、Go、Rust、Java、C#、C++、PHP、Swift、HTML、CSS)であれば保持されます。それ以外の言語指定は削除されます。
カレンダーに保存されるものはすべて記録であり、種類ごとに専用のコマンドがあります:hey event、hey todo、hey journal、hey habit、hey timetrack。日付を指定しない場合、これらのコマンドはアカウントのタイムゾーンを読み取って今日の日付を判断します。アカウント情報の読み取りを省略するには、日付を指定してください。
全文を書き換える項目への追記
hey contact note set と hey journal write はメモまたはエントリー全体を置き換えます。追記機能はありません。追記するには、読み取って変更し、全文を書き戻してください。&& は残してください。読み取りに失敗した場合に書き込みへ進まないようにするためです。読み取りと書き込みはアトミックではないため、読み取り後すぐに書き込んでください。
連絡先メモ。 note_markdown_lossless が true の場合、note_markdown にメモ全体が格納されています。読み取り時にフラグ自体を確認し、false の場合は失敗するため、何も書き込まれません:
note=$(hey contact note show 12345 --jq 'if .data.note_markdown_lossless then .data.note_markdown else error("note_markdown would drop part of this note: change note_html with --note-html") end') &&
printf '%s\n\nMoved to the Lisbon office in March.\n' "$note" | hey contact note set 12345
false の場合、メモには Markdown では表現できないマークアップが含まれています。代わりに HTML に追記してください:
note=$(hey contact note show 12345 --jq '.data.note_html') &&
hey contact note set 12345 --note-html "$note<p>Moved to the Lisbon office in March.</p>"
ジャーナルエントリー。 content_markdown_lossless を使う点は同じです。エントリーのない日についても、読み取りは失敗します:
entry=$(hey journal read 2026-03-15 --jq 'if .data.content_markdown_lossless then .data.content_markdown else error("content_markdown would drop part of this entry, or there is none: change content with --content-html") end') &&
printf '%s\n\nBooked the venue for the second day.\n' "$entry" | hey journal write 2026-03-15
entry=$(hey journal read 2026-03-15 --jq '.data.content // error("no journal entry for this day")') &&
hey journal write 2026-03-15 --content-html "$entry<p>Booked the venue for the second day.</p>"
認証
データコマンドは、HEY がすでに保存している認証情報を使用し、有効期限が切れる OAuth トークンを自動的に更新します。ログイン前の確認を行わず、要求されたデータコマンドを実行してください。
データコマンドが終了コード 3 と "code": "auth" を返す場合、または could not read stored credentials で失敗する場合、そのプロセスでは認証を利用できません。macOS で Codex を使用している場合、サンドボックスによって HEY CLI が Keychain に保存した認証情報が隠されることがあります。タスクをブロック扱いとして報告する前に、ハーネスの通常の承認フローを使い、サンドボックス権限を昇格させて hey auth status --json を一度再試行してください。権限昇格は、この読み取り専用コマンドだけに限定してください。応答の data.authenticated が true の場合は、ユーザーが要求した正確な hey コマンドだけを、別途、単一コマンドの承認を得て再実行してください。data.authenticated が false の場合は、タスクがブロックされていると報告し、ユーザーにターミナルで hey auth login を実行するよう伝えてください。ユーザーに代わって無人で実行してはいけません。ステータスコマンドが exit status 36 のようなキーリングエラーで失敗した場合、問題はログインではなく、hey auth login でも解決しません。タスクがブロックされていると報告し、エラーの hint を伝えて停止してください。
macOS の security コマンドを実行して Keychain の内容を読み取ったり、認証情報を表示またはコピーしたり、認証情報をファイルに移したりしてはいけません。サンドボックスをグローバルに無効化してはいけません。認証の回避策として HEY_NO_KEYRING=1 を設定してはいけません。
パイプ経由のコマンド、機械可読形式の出力を行うコマンド、および非 TTY コマンドでは、サインインを促すプロンプトは表示されません。エージェントハーネスがコマンドを PTY で実行する場合は、ログインがないときに対話型プロンプトを開く代わりに、同じ対処可能な認証エラーが返されるよう HEY_NONINTERACTIVE=1 を設定してください。