Ocean Code
Away from the Mac
Slack Remote posts every wait, finish and block of your sessions in one private channel and takes the answer from a button or a thread reply; the Notification hook sends the same events anywhere else.
A long run does not need you at the keyboard, but it does need you when it hits a permission or a question. Ocean Code reaches you two ways: Slack Remote, which is two-way, and the Notification hook, which is one-way into anything you like.
Slack Remote
Every Ocean Code window on the Mac connects to one Slack app over Socket Mode, so the Mac needs no open port and no relay. When a session waits for you, finishes or is blocked, the engine posts one message in one private channel, and your phone gets it as a notification. Nothing is posted while a turn works.
| Event | What is posted |
|---|---|
| A permission ask | The permission and its patterns, with the buttons Allow once, Always and Deny. |
| A question | The question and its options; one to five options get a button each, anything else ends with Reply in this thread. |
| Done | Done — and the first line of the answer. |
| Blocked | Blocked — and the reason: an error, a refusal or a bound. |
Every message starts with #<code> · <title> · <folder>, so you know which session speaks. A sub-agent's ask is posted for its root session. Once an ask is answered, in Slack or in the window, the message loses its buttons and says how it ended (Allowed once from Slack, Denied, Answered: …, Expired after 30 min).
Answering. Press a button, or reply in the message's thread: yes, allow or ok allows once, always allows from then on, no or deny denies, any other text denies with your text as the correction, and stop interrupts the session. A reply with no open ask becomes the session's next prompt, and the prompt and its reply show in the window that has the session open, as if typed there. Top-level messages and other bots are ignored: a prompt reaches a session only through one of its threads.
Several windows, several Macs. Every window that hosts the engine connects: the pager, oceancode acp in Xcode or Zed, and oceancode serve; one-shot runs never do. On one Mac a reply reaches the window that owns the session within about two seconds, whichever window Slack handed it to. Give each Mac its own Slack app, named after the Mac; the apps can share one channel.
Setting it up
- Create the app from the manifest
At api.slack.com/apps (opens in a new tab), Create New App → From an app manifest, pick your workspace and paste the manifest from the Slack reference. Install it to the workspace and copy the Bot User OAuth Token (
xoxb-…); under Basic Information → App-Level Tokens, generate a token with the scopeconnections:writeand copy it (xapp-…). - Make a private channel
Create a private channel and invite the bot (
/invite @Ocean Code). It must be private: whoever can write in the channel can run prompts on this Mac, andconnectrefuses a public one. Copy the channel id from the channel's details. - Connect
oceancode slack connect --channel C0123456789It reads
SLACK_BOT_TOKENandSLACK_APP_TOKENfrom the environment or asks for them, checks both tokens and the channel, postsOcean Code connected from <hostname>and printsSLACK_CONNECT_OK. Open a new window, or restart the open ones: a window reads the tokens when it starts.
oceancode slack status shows the team, the bot, the channel and whether the bridge is on; oceancode slack disconnect removes the tokens; OC_SLACK=0 turns it off for one window, which unattended automation should set. Flags and exit codes: CLI reference.
Anyone who can write in the channel can run prompts on your Mac. Keep the channel private and small.
The Notification hook
Notification is a hook event that fires when a root session needs you or has stopped: permission_prompt, elicitation_dialog (a question), idle_prompt (the turn finished) and blocked. It runs in the background, cannot block or change anything, and carries one line of text with the session's id, code, title and folder. It is shaped like Claude Code's event, so a Claude Code Notification hook runs unchanged, and the matcher permission_prompt|elicitation_dialog keeps it to the moments a session waits for you.
A Slack incoming webhook is one line of settings; a push service, a desktop notifier or a script is the same shape. The payload, the matcher and the webhook recipe are in the hooks reference.
Next
- Several sessions, one Mac: the codes the Slack messages name, and the board.
- Long runs and sub-agents: what a run posts, and why it stopped.