Skip to content

Add support for OSC777 (Send Notification) - #20012

Merged
Carlos Zamora (carlos-zamora) merged 22 commits into
mainfrom
dev/cazamor/toast/osc777
Jun 4, 2026
Merged

Add support for OSC777 (Send Notification)#20012
Carlos Zamora (carlos-zamora) merged 22 commits into
mainfrom
dev/cazamor/toast/osc777

Conversation

@carlos-zamora

Copy link
Copy Markdown
Member

Summary of the Pull Request

targets #20010

This adds support for the OSC 777 ; notify ; title ; body ST sequence. This allows client applications to send a notification to the Terminal. When this notification is clicked, it summons the terminal window that sent it.

Validation Steps Performed

# in PowerShell. Terminal should not be focused.
sleep 2; Write-Output "`e]777;notify;Hello;This is a notification`a"

PR Checklist

Heavily based on #19938
Co-authored by Mike Griese (@zadjii-msft)

Comment thread src/terminal/adapter/adaptDispatch.cpp Outdated
Comment thread src/terminal/adapter/adaptDispatch.cpp
Comment thread src/terminal/parser/OutputStateMachineEngine.cpp Outdated
Comment thread src/terminal/adapter/ITermDispatch.hpp Fixed
Comment thread src/terminal/adapter/adaptDispatch.cpp Fixed
Comment thread src/terminal/adapter/adaptDispatch.cpp Fixed
Comment thread src/terminal/adapter/adaptDispatch.hpp Fixed
Comment thread src/terminal/adapter/termDispatch.hpp Fixed
Comment thread src/terminal/parser/OutputStateMachineEngine.cpp Fixed
@github-actions

This comment has been minimized.

## Summary of the Pull Request
Targets #20010 

Manually assign an AUMID to our process when we're running unpackaged.
Main difference from #19937 is what AUMID we use. Before, it was per
branding, but the `WindowEmperor` already appends an exe path hash for
unpackaged instances to prevent crosstalk. Here, we're just using the
same pattern: `Microsoft.WindowsTerminal.<hash>`.

Heavily based on #19937
Co-authored by @zadjii-msft
Comment thread .github/actions/spelling/expect/expect.txt Fixed
@github-actions

This comment has been minimized.

Comment thread src/terminal/adapter/adaptDispatch.cpp Outdated
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Base automatically changed from dev/cazamor/toast/base to main April 30, 2026 00:24
@microsoft-github-policy-service microsoft-github-policy-service Bot added Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Area-VT Virtual Terminal sequence support Product-Terminal The new Windows Terminal. labels Apr 30, 2026
Comment thread src/cascadia/inc/ControlProperties.h Outdated
Comment thread src/cascadia/TerminalApp/Resources/en-US/Resources.resw
Comment thread src/cascadia/TerminalApp/DesktopNotification.cpp Outdated
Comment thread src/cascadia/TerminalApp/DesktopNotification.cpp
Comment thread src/cascadia/TerminalApp/TabManagement.cpp
Comment thread src/cascadia/TerminalApp/IPaneContent.idl
@microsoft-github-policy-service microsoft-github-policy-service Bot added Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something and removed Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something labels May 4, 2026
@carlos-zamora

Copy link
Copy Markdown
Member Author

Feedback from Bug Bash (5/5)

  • should be disabled by default

Dustin L. Howett (@DHowett) Got a reason why? Is it that we just don't want applications to spam the user with notifications?

@carlos-zamora

Copy link
Copy Markdown
Member Author

Updated default to false.

Validated that this works. Can be tested using:

Write-Host "$([char]27)]777;notify;Title;Message$([char]27)\"

Comment on lines +2790 to +2794
"compatibility.allowOSC777": {
"default": false,
"description": "When set to true, applications can send OSC 777 escape sequences to trigger desktop toast notifications with a custom title and body.",
"type": "boolean"
},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

fwiw i discovered today that there's also osc 9

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You also discovered that six years ago in #7718 (comment). 😁

<comment>{Locked="OSC 52"}{Locked="Manipulate Selection Data"}Header for a control to toggle support for applications to change the contents of the Windows system clipboard.</comment>
</data>
<data name="Profile_AllowOscNotifications.Header" xml:space="preserve">
<value>Allow OSC 777 (Desktop Notification) to show toast notifications</value>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

future us todo: when we add support for the other OSC strings for notifying, this string will need to get updated

@carlos-zamora
Carlos Zamora (carlos-zamora) dismissed Dustin L. Howett (DHowett)’s stale review June 4, 2026 00:53

Applied feedback. Review is old/stale. Got two approvals.

If there's any more feedback, happy to fix it after this merges.

@carlos-zamora
Carlos Zamora (carlos-zamora) merged commit 93bdbfa into main Jun 4, 2026
20 checks passed
@carlos-zamora
Carlos Zamora (carlos-zamora) deleted the dev/cazamor/toast/osc777 branch June 4, 2026 00:54
Takeaki Kobayashi (takecchi) added a commit to takecchi/codiva that referenced this pull request Jul 30, 2026
## 概要

codiva の作業完了通知などのポップアップを**クリックするとスクリプトエディタ(Script
Editor)が開く**不具合を修正しました。通知をクリックしたら codiva を動かしているターミナルに戻れるようになります。

## 原因

macOS の通知センターは通知を**アプリバンドル単位**で管理していて、バンドルを持たないプロセスは通知を出せません。`osascript`
は単体バイナリなので、そこから出した `display notification` は AppleScript の代表バンドル
`com.apple.ScriptEditor2`(= スクリプトエディタ)名義で投函されます。


通知クリックは「送信元アプリをアクティブにする」動作なので、結果としてスクリプトエディタが開いていました(通知の見出しも「スクリプトエディタ」になっていたはずです)。`osascript`
には `terminal-notifier` の `-sender` 相当の指定がなく、`tell application id "…" to
display notification` で端末アプリ名義にする手は TCC(自動化)の許可プロンプトが必要になります。

同じ症状は他の CLI
でも報告されています([opencode#23446](https://github.com/anomalyco/opencode/issues/23446))。

## 対応

**端末自身に通知を出させる OSC シーケンスを優先**し、`osascript` / `notify-send`
は非対応端末向けのフォールバックに落としました。端末エミュレータが投函するので通知は端末アプリ名義になり、クリックでそのターミナルが前面に来ます。OSC
52(クリップボード)と同じ仕組みなので追加依存はなく、SSH / コンテナ越しでも動きます。

| 方言 | 形 | 対応端末 |
|---|---|---|
| OSC 777 | `ESC ] 777 ; notify ; <title> ; <body> BEL` | Ghostty /
WezTerm / foot |
| OSC 9 | `ESC ] 9 ; <body> BEL`(本文1つだけ) | iTerm2 |
| OSC 99 | `ESC ] 99 ; i=<id>:d=0:p=title:e=1 ; <base64> ST` +
`d=1:p=body` | kitty |

### 実装のポイント(レビューで潰した罠)

- **`TERM_PROGRAM` / `TERM` だけに頼らない**: tmux は `TERM_PROGRAM` を `tmux`
で上書きし(tmux 3.2 以降)`TERM` も `screen-*` に化けるため、それだけ見ると **tmux
内では必ず判定漏れして元の症状に戻る**。端末が自前で撒く `GHOSTTY_BIN_DIR` /
`GHOSTTY_RESOURCES_DIR` / `WEZTERM_PANE` / `WEZTERM_EXECUTABLE` /
`KITTY_WINDOW_ID` / `ITERM_SESSION_ID` / `LC_TERMINAL` も見る(`LC_TERMINAL`
は ssh が既定で転送するので、リモートの codiva からでも手元の iTerm2 に出る)。
- **Windows Terminal と urxvt は意図的に判定しない**: WT の通知用 OSC 777 は
`allowOSC777` 設定が既定
false([microsoft/terminal#20012](https://github.com/microsoft/terminal/pull/20012))で、OSC
9 の方は ConEmu 方言の数値サブコマンド専用。urxvt の OSC 777 は同梱されていない perl
拡張へ丸投げする汎用口。OSC は解釈されたか分からないため、誤判定すると**通知が無音で消えて、動いていた OS 通知まで失う**。
- **入力の無害化**: セッションタイトルは LLM がリポジトリ内容から作る非信頼入力なので、制御文字(C0 / DEL / **C1**
— UTF-8 のまま U+009C を ST、U+009B を CSI と解釈する端末がある)を空白へ潰し 120 文字で切る。OSC 777
の title 内 `;` はフィールド境界と誤読されるので `,` へ、OSC 9 は本文が `9;4;70`
のようなプログレスバー指示に化けないよう `;` を全置換。OSC 99 は payload を base64(`e=1`)で運ぶ。
- **OSC 99 の通知 id は `<pid>-<連番>`**: 同じ id の chunk は上書き・連結されるため、1 端末で
codiva を 2 つ動かしても衝突しないように pid を混ぜる。
- 非 TTY のときはエスケープを書かない(通知にならずゴミが残るだけ)。tmux 内は DCS
パススルーで包む(`allow-passthrough on` が必要。`wrapForTmux` を `clipboard.ts` から
`terminal-mode.ts` へ移して共用)。
- stdout への `write` は try/catch で握り潰す(best-effort の契約どおり、端末が閉じられた直後の遷移で
commit 経路を壊さない)。

## 変更ファイル

- `src/utils/notify.ts`: `detectNotifyProtocol` /
`buildNotifySequence`(純関数)を追加し、`notify()` を OSC → OS コマンドの2経路に
- `src/utils/terminal-mode.ts` / `src/utils/clipboard.ts`: `wrapForTmux`
を共通化
- `src/utils/notify.spec.ts`: 端末判定と3方言のシーケンス組み立てをテーブルドリブンで追加(tmux 内・ssh
越し・意図的な非検出・制御文字・切り詰め・write 失敗)
- `README.md` / `docs/ARCHITECTURE.md` / `docs/TECH_NOTES.md` /
`.claude/rules/git-and-io.md`: 挙動と設計判断・実測結果を反映

## テスト

- [x] `npm run lint`
- [x] `npm run typecheck`(このワークツリーでは既存の `marked`
未解決エラーのみ。今回の変更に起因するものなし)
- [x] `src/utils/notify.spec.ts` / `clipboard.spec.ts` 緑(47 テスト)
- [ ] CI での `lint → typecheck → test → build` 全通過
- [ ] 手動確認(TTY 必須): Ghostty で完了通知が「Ghostty」名義で出て、クリックで Ghostty が前面に来ること
- [ ] 手動確認: tmux 内(`allow-passthrough on`)でも同様に通知が出ること
- [ ] 手動確認: Terminal.app ではフォールバック経路で通知が出ること(この経路は従来どおりスクリプトエディタ名義)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-VT Virtual Terminal sequence support Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal. zBugBash-Consider

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Send Desktop Notification via VT Sequence (OSC777)

6 participants