AI agents are useful because they keep working after you switch tabs. That's also why they're easy to forget about — by the time the result is ready, you've already moved on three times.
Dev Island gives that background work a small, persistent home on macOS. A capsule sits in your menu bar (or curls around the notch on a 14"/16" MacBook Pro), showing how many tasks are in flight and what state they're in. Click it and the full task list slides down. A task starts asking for input? The bar turns yellow. Something failed? Red. Everything done? Green. Silence? Gray.
It's a Dynamic Island for the agentic stuff happening on the other side of the internet.
The bar carries five states, ordered by priority — the highest one wins:
| Color | State | Meaning |
|---|---|---|
| 🟡 | Waiting | An agent paused and is asking for input |
| 🔴 | Failed | At least one task errored out and you should look |
| 🟢 | Running | Work is in flight |
| 🟦 | Completed | Done, nothing to do |
| ⚪ | Idle | No tasks, or sync is paused |
Hover the bar and it widens to show the current task title. Click it and the panel expands into a scrollable task list with one-click open-in-browser. Click outside or press Esc to collapse it back.
Go to devisland.app → click Download for Mac → open Dev-Island.dmg → drag Dev Island.app onto Applications.
(A zip with the identical app ships on every release for scripted installs and stable direct-download URLs.)
The app is signed with a Developer ID and notarized by Apple, so it opens with zero Gatekeeper warnings on first launch.
Coming soon. Once the public tap is published:
brew tap sheepxux/dev-island
brew install --cask dev-islandThe Cask will declare depends_on cask: "cloudflared" so realtime webhook
updates work out of the box.
Requires macOS 14+ and a Swift 6 toolchain (Xcode 16 ships one):
git clone https://github.com/sheepxux/Dev-Island.git
cd Dev-Island
swift run IslandApp # dev launch
./scripts/build-app.sh # produces build/Dev Island.app (ad-hoc signed)- Click the gear icon in the expanded panel (or pick Settings from the menu)
- Paste your Manus API key (
sk-…) and hit Connect - The status dot turns green. That's it — your live tasks start syncing.
Keys are stored in the macOS Keychain. Disconnect at any time from the same
settings pane. Optional Launch at Login hooks up via SMAppService, no
LaunchAgent files dropped on disk.
Dev Island prefers a realtime webhook path. When cloudflared is on your
$PATH (or installed via the Homebrew Cask), the app spins up a tunnel,
registers a webhook with Manus, and receives task transitions as they happen.
If cloudflared is missing, broken, or your network blocks the tunnel, the app
falls back to 60-second polling automatically. You don't lose any state, you
just see updates within a minute instead of a few hundred milliseconds. The app
prints a small "degraded" reason in the status dot tooltip so you know which
mode you're in.
| Source | Status |
|---|---|
| Manus | ✅ Available |
| Claude Code | ✅ Available (local hooks, no tunnel needed) |
| Codex CLI | ✅ Available (local hooks, no tunnel needed) |
| Cursor | ✅ Available (local hooks, no tunnel needed) |
Claude Code, Codex and Cursor need no API key: flip the toggle in
Settings → Connected Services. Dev Island installs a fire-and-forget hook
(into ~/.claude/settings.json / ~/.codex/hooks.json /
~/.cursor/hooks.json) that reports session
lifecycle events (start / needs-input / approval-request / done / failed) to
a localhost-only endpoint. New sessions appear in the island within
milliseconds; clicking one opens the project folder.
The connector layer is intentionally pluggable — IslandCore exposes an
AgentConnector protocol, and adding a new source is a matter of writing
fetchTasks() + (optionally) a webhook handler that emits WebhookPayload.
SPM-native, four targets, single shared contract:
| Target | Role |
|---|---|
IslandApp |
Tiny @main shim + AppDelegate |
IslandAppLib |
SwiftUI views, windows, animations, settings, notifications |
IslandCore |
Connectors, persistence (SQLite + Keychain), webhook server, tunnel |
IslandCoreCLI |
Headless integration test harness |
UI ↔ core boundary is the public TaskStore surface. Both sides ship in the
same repo because the shared contract evolves together; cross-side breaking
changes go through docs/INTERFACE_CONTRACT.md.
┌────────────────────────────┐ ┌─────────────────────────────────┐
│ IslandAppLib │ │ IslandCore │
│ │ │ │
│ IslandRootView ────────┼───→│ TaskStore.shared │
│ NotchPanelView │ │ ├─ ManusAPIClient │
│ SettingsView │ │ ├─ TunnelManager (cf'ed) │
│ StatusDot │ │ ├─ PollingFallback (60s) │
│ │ │ ├─ WebhookServer │
└────────────────────────────┘ │ └─ SQLiteStore + Keychain │
└─────────────────────────────────┘
| Area | State |
|---|---|
| macOS island UI (notched + non-notched) | ✅ Shipping |
| Manus task sync (polling, webhook fallback path) | ✅ Shipping |
| Settings + Launch at Login + banner notifications | ✅ Shipping |
| Signed + notarized public release | ✅ v0.1.1 on Releases |
| Homebrew Cask tap | 🚧 Draft in dist/homebrew-island/ |
| Claude Code connector (local hooks) | ✅ Shipping |
| Codex connector (local hooks) | ✅ Shipping |
| Cursor connector (local hooks) | ✅ Shipping |
Ideas, bug reports, and connector PRs welcome. If you're adding a new agent
source, the cleanest entry point is IslandCore/Sources/IslandCore/Connectors/
— start by reading ManusConnector.swift and the surrounding webhook +
polling glue.
For interface-contract changes (anything touching TaskStore's public API),
see docs/INTERFACE_CONTRACT.md first.
MIT. Use it, fork it, ship your own version with a new icon, send weird agent task notifications to your friends. Just keep the copyright notice intact.
devisland.app · Issues · Releases

