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
18 changes: 9 additions & 9 deletions packages/notch-mod/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "switchboard-notch",
"version": "0.1.4",
"description": "Claude's questions drop from your Mac's notch as a native card. Pick with 1-4, type your own answer, or press esc to answer in Claude Code as usual.",
"name": "ask-notch",
"version": "0.3.0",
"description": "Claude's questions drop from your Mac's notch as a card. Click an option, pick with 1-4, type your own answer, or press esc to answer in Claude Code as usual.",
"author": {
"name": "sameeeeeeep",
"url": "https://github.com/sameeeeeeep/switchboard"
},
"displayName": "Switchboard Notch",
"homepage": "https://thelastprompt.ai/switchboard",
"repository": "https://github.com/sameeeeeeep/switchboard-notch",
"displayName": "Ask Notch",
"homepage": "https://github.com/sameeeeeeep/ask-notch",
"repository": "https://github.com/sameeeeeeep/ask-notch",
"license": "MIT",
"keywords": [
"notch",
Expand All @@ -18,7 +18,7 @@
"AskUserQuestion"
],
"icon": "./assets/icon.png",
"documentationUrl": "https://github.com/sameeeeeeep/switchboard-notch#readme",
"supportUrl": "https://github.com/sameeeeeeep/switchboard-notch/issues",
"privacyPolicyUrl": "https://github.com/sameeeeeeep/switchboard-notch#privacy"
"documentationUrl": "https://github.com/sameeeeeeep/ask-notch#readme",
"supportUrl": "https://github.com/sameeeeeeep/ask-notch/issues",
"privacyPolicyUrl": "https://github.com/sameeeeeeep/ask-notch#privacy"
}
99 changes: 66 additions & 33 deletions packages/notch-mod/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Switchboard Notch
# Ask Notch

When Claude asks you something, the question drops from your Mac's notch as a native card, so you
can answer without switching back to the terminal.
When Claude asks you something, the question drops from your Mac's notch as a card, so you can
answer without switching back to the terminal.

![A question from Claude shown as a card at the Mac notch, with three numbered options and a text box](assets/card-light.png)

Expand All @@ -14,14 +14,15 @@ can answer without switching back to the terminal.

Needs macOS 13+ and Claude Code **v2.1.287** or later (`claude --version`). It is a Claude Code
[mod](https://code.claude.com/docs/en/plugins/mods/overview): it hooks Claude's `AskUserQuestion`
tool and nothing else.
tool and nothing else. Nothing is compiled: the card is a JavaScript file that macOS's own
`osascript` runs.

## Try it for one session

Nothing is installed and nothing is written to your settings:

```sh
claude --plugin-url https://github.com/sameeeeeeep/switchboard-notch/releases/latest/download/switchboard-notch.zip
claude --plugin-url https://github.com/sameeeeeeep/ask-notch/releases/latest/download/ask-notch.zip
```

Ask Claude something that makes it ask you back, or run `/notch test`.
Expand All @@ -31,32 +32,46 @@ Ask Claude something that makes it ask you back, or run `/notch test`.
In Claude Code (v2.1.275+ adds the marketplace and installs in one step):

```text
/plugin install switchboard-notch --marketplace sameeeeeeep/switchboard-notch
/plugin install ask-notch --marketplace sameeeeeeep/ask-notch
```

Updates: `claude plugin update switchboard-notch@switchboard-notch`.
Updates: `claude plugin update ask-notch@ask-notch`.

## Settings

Say what you want after `/notch`, in your own words: `/notch put it by my mouse`, `/notch pause for now`,
`/notch bring the cat`, `/notch show me one`. Claude reads it and changes the setting. On its own, `/notch`
shows the current settings. The words below skip Claude and take effect instantly:

| Command | Effect |
| --- | --- |
| `/notch cursor` | Open cards beside the pointer instead of at the notch |
| `/notch notch` | Back to the notch |
| `/notch companion cat` | A small painted cat hops out beside the card and waits with you |
| `/notch companion off` | No companion (the default) |
| `/notch off` / `/notch on` | Use Claude Code's own dialog / the card |
| `/notch test` | Show a test card |

Multi-select, free-text and number questions always use Claude Code's own form.

## Choices come to you

While cards are on, Claude asks with `AskUserQuestion` whenever it would otherwise list options in its reply
("A or B?", "go ahead?"), so those choices arrive as a card at the notch. The plugin adds one short paragraph saying
so to Claude's system prompt while cards are on (none while they're off), and ships the same guidance as a skill,
`ask-at-the-notch`.

## Examples

Any request where Claude stops to ask you a question shows the card. Three to try:

1. **A design choice.** "Add a settings page to this app. Ask me which layout to use before you
build it." The card shows the layouts Claude proposes, with its pick highlighted. Press **1–4** or **↵**.
build it." The card shows the layouts Claude proposes, with its pick highlighted. Click one, or
click the card and press **1–4** or **↵**.
2. **A risky step.** "Clean up the old migration files, but ask me before deleting anything." Claude's
question lands at the notch while you work in another app; answer it there and Claude carries on.
3. **Your own answer.** "Help me name this CLI tool and ask me to choose." Ignore the options, type
a name in the card's text box, and press **↵**. Claude receives exactly what you typed.
3. **Your own answer.** "Help me name this CLI tool and ask me to choose." Ignore the options, click
the card's text box, type a name, and press **↵**. Claude receives exactly what you typed.

`/notch test` shows a sample card without asking Claude anything.

Expand All @@ -71,46 +86,64 @@ as usual.
## Troubleshooting

- **No card appears.** Run `claude --version` (needs v2.1.287+), then `/plugin` and look for
`switchboard-notch` in the `mods active` line under the tabs. Run `/notch test`. If `/notch` is off, run `/notch on`.
`ask-notch` in the `mods active` line under the tabs. Run `/notch test`. If `/notch` is off, run `/notch on`.
- **The card opens on the wrong screen.** Run `/notch cursor` to open it beside the pointer.
- **You'd rather answer in the terminal.** Press **esc** on any card, or run `/notch off`.

## What it does on your machine

Everything the mod does is in [`hooks/register.js`](hooks/register.js) (about 90 lines):
The mod is [`hooks/register.js`](hooks/register.js) (about 100 lines) and the card is
[`helper/card.js`](helper/card.js) (about 600 lines). Both are plain JavaScript you can read; the
plugin ships no compiled code.

- **Which tool it answers, and when.** It handles only Claude Code's `AskUserQuestion` tool, and
only single-choice questions. When you pick or type an answer in the card, the mod returns that
answer in place of Claude Code's own question dialog, in the same shape the dialog returns. If you
press esc, the card times out (9 minutes), the question is multi-select, text or number, or the
card can't start, it hands the question back to Claude Code's dialog unchanged.
- **The one program it starts, and why.** It runs `helper/sb-card` (in this plugin) to draw the card,
with one argument: a JSON object holding the question, its options, and where to show the card.
It starts nothing else and runs no shell.
- **What it reads, and where that goes.** It reads the question Claude is asking (part of your
conversation) and passes it to `helper/sb-card` as that argument. `helper/sb-card` prints your
answer and exits, and the mod gives the answer back to Claude. Nothing is sent anywhere else: the
mod makes no network requests, and neither does `helper/sb-card`.
- **What it stores.** Only your `/notch` setting (on or off, notch or cursor), in Claude Code's
local storage for this plugin.

`helper/sb-card` is a small native macOS program built from
[`helper/sb-card.swift`](helper/sb-card.swift) (about 230 lines of AppKit and SwiftUI). It needs no
permissions and writes no files. It is signed with Developer ID (STAYOFT VENTURES PRIVATE LIMITED,
55354KFTHU) and notarized by Apple. To list the mod's hooks and calls yourself, run
`claude plugin validate` on this directory.
- **The one program it starts, and why.** It always runs the same fixed command,
`/usr/bin/osascript -l JavaScript helper/card.js`, from this plugin's own folder. `osascript` is
macOS's built-in script runner; the plugin needs it because a Claude Code mod can only draw inside
Claude Code's window, and the card has to appear at the Mac's notch. The question, its options,
where to show the card and, if you turned one on, the companion's folder go to the card on its
**standard input** as one JSON object. It starts nothing else and runs no shell.
- **What the card does.** `helper/card.js` uses macOS's JavaScript bridge to AppKit to draw one
window, reads the pointer position (for `/notch cursor`) and, with a companion, the pictures in
`assets/companion/`. It prints your answer as one line of JSON and exits. It makes no network
requests, writes no files, reads no environment variables and needs no permissions. It refuses
the keyboard until you click it, and appears without activating, so it can't take keystrokes
meant for the app you're using.
- **What it reads, and where it sends it.** It reads the question Claude is asking (part of your
conversation) and sends it to exactly one place: the local `osascript` process above, on its
standard input. The card prints your answer on standard output and exits, and the mod gives the
answer back to Claude. Nothing leaves your Mac: no network requests, no files written, no
credentials or environment variables read.
- **Standing in for a tool.** The mod answers `AskUserQuestion` in place of Claude Code's dialog
only when you answer on the card; every other case calls through to Claude Code's own dialog.
- **Settings in plain words.** `/notch` followed by words it doesn't recognise sends Claude one
prompt that quotes them. Claude then changes the setting through the plugin's own tool,
`mcp__ask-notch__settings` (on/off, notch/cursor, companion, test card). The tool reads and writes
only the settings below.
- **The system prompt note and the skill.** While cards are on, the mod adds one fixed paragraph to
Claude's system prompt (`CHOICES_NOTE` in `hooks/register.js`) asking it to put choices to you
with `AskUserQuestion`. `skills/ask-at-the-notch/SKILL.md` says the same at length. Both are plain
text and run nothing.
- **What it stores.** Only your `/notch` settings (on or off, notch or cursor, companion), in
Claude Code's local storage for this plugin.

To list the mod's hooks and calls yourself, run `claude plugin validate` on this directory.

## Privacy

Switchboard Notch collects nothing. The question, its options and your answer pass only between
Claude Code and `helper/sb-card` on your Mac. There is no network access, no analytics and no
account. The only thing saved is your `/notch` setting (on or off, notch or cursor), in Claude
Code's local storage for this plugin; uninstalling the plugin removes it.
Ask Notch collects nothing. The question, its options and your answer pass only between Claude Code
and `osascript` running `helper/card.js` on your Mac. There is no network access, no analytics and
no account. The only thing saved is your `/notch` settings (on or off, notch or cursor, companion),
in Claude Code's local storage for this plugin; uninstalling the plugin removes it.

## Support

Report problems or ask questions at
[github.com/sameeeeeeep/switchboard-notch/issues](https://github.com/sameeeeeeep/switchboard-notch/issues).
[github.com/sameeeeeeep/ask-notch/issues](https://github.com/sameeeeeeep/ask-notch/issues).
For security issues, email [sameeeeeeep@gmail.com](mailto:sameeeeeeep@gmail.com) instead of opening a public issue.

## Develop
Expand All @@ -119,6 +152,6 @@ The source lives in [`packages/notch-mod`](https://github.com/sameeeeeeep/switch
in the Switchboard repo, which also holds the build and release scripts; this repo is a mirror.

```sh
claude --plugin-dir "$PWD" # load a checkout for one session; edits hot-reload
claude --plugin-dir /path/to/ask-notch # load a checkout for one session; edits hot-reload
claude plugin test # unit tests (no session needed)
```
Binary file modified packages/notch-mod/assets/card-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified packages/notch-mod/assets/card-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/notch-mod/assets/companion/cat/sit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions packages/notch-mod/assets/companion/clawd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Clawd companion: placeholder (art pending the owner's decision)

**Status: no art here on purpose.** `/notch companion clawd` is a hidden option (not in the README or
the directory listing). With this folder holding no `sequence.json`, the card shows no companion, so
the option is a safe no-op until a decision is made.

Why it's empty: Clawd is Anthropic's character. Whether Ask Notch ships a Clawd companion in its
Claude directory submission is the owner's call (trademark and review risk), so no Clawd artwork has
been copied from anywhere into this repo. `build.sh` and `publish.sh` leave this folder out of the
published plugin.

## To fill the slot (only after the decision)

Use the same contract as `../cat/` (see `listing/make-companion.py`, which builds it):

- `sequence.json`: `canvas` `[w, h]` in points; `overlap` (points of the canvas that sit behind the
card's right edge); `intro` `{ delay_ms, frames: [[file, ms], ...] }` played when the card appears;
`idle` (file shown while waiting); `settle` `{ after_s, frames }` played once after `after_s`.
- Frames: transparent PNGs at 2× the canvas size, all the same size, feet on the canvas's ground line,
so the card only swaps pictures. File names: letters, digits, `.`, `-`, `_`, ending in `.png`.
- Keep the folder small (the cat is about 220 KB).

Then remove the `-x 'assets/companion/clawd/*'` exclusion in `build.sh`, the matching `rm` in
`publish.sh`, and document `/notch companion clawd` in the README and listing.
32 changes: 9 additions & 23 deletions packages/notch-mod/build.sh
Original file line number Diff line number Diff line change
@@ -1,28 +1,14 @@
#!/bin/sh
# Build helper/sb-card as a universal binary, sign it with Developer ID, notarize it, and package
# dist/switchboard-notch.zip for `claude --plugin-url`.
# Set SKIP_NOTARIZE=1 for a local build.
# Package dist/ask-notch.zip for `claude --plugin-url`. Nothing is compiled or signed: the card is
# helper/card.js, run by macOS's own /usr/bin/osascript.
set -eu
cd "$(dirname "$0")"

IDENTITY="Developer ID Application: STAYOFT VENTURES PRIVATE LIMITED (55354KFTHU)"
TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT

for arch in arm64 x86_64; do
swiftc -O -target "$arch-apple-macos13" -o "$TMP/sb-card-$arch" helper/sb-card.swift \
-framework AppKit -framework SwiftUI
done
lipo -create -output helper/sb-card "$TMP/sb-card-arm64" "$TMP/sb-card-x86_64"
codesign --force --options runtime --timestamp --identifier ai.thelastprompt.sb-card \
--sign "$IDENTITY" helper/sb-card

if [ "${SKIP_NOTARIZE:-0}" != 1 ]; then
ditto -c -k helper/sb-card "$TMP/sb-card.zip"
xcrun notarytool submit "$TMP/sb-card.zip" --keychain-profile relay-notary --wait
fi

claude plugin validate "$PWD" >/dev/null
mkdir -p dist
rm -f dist/switchboard-notch.zip
zip -qr dist/switchboard-notch.zip .claude-plugin/plugin.json hooks helper/sb-card assets README.md
echo "built dist/switchboard-notch.zip"
rm -f dist/ask-notch.zip
# Leave out macOS/Windows system files (the directory's validator blocks them) and the Clawd companion
# slot, which holds no art until the owner decides (assets/companion/clawd/README.md).
zip -qr dist/ask-notch.zip .claude-plugin/plugin.json hooks helper skills assets README.md \
-x '*.DS_Store' -x '*Thumbs.db' -x '*desktop.ini' -x '__MACOSX/*' -x 'assets/companion/clawd/*'
echo "built dist/ask-notch.zip ($(du -h dist/ask-notch.zip | cut -f1))"
Loading
Loading