omnish 1.6.5 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +78 -2
  2. package/README.md +30 -18
  3. package/config.example.json +1 -0
  4. package/dist/downloads/omnish-claude/install.sh +174 -0
  5. package/dist/downloads/omnish-claude/uninstall.sh +114 -0
  6. package/dist/downloads/omnish-claude.tar.gz +0 -0
  7. package/dist/downloads/omnish-cursor/install.sh +162 -0
  8. package/dist/downloads/omnish-cursor/uninstall.sh +107 -0
  9. package/dist/downloads/omnish-cursor.tar.gz +0 -0
  10. package/dist/index.js +424 -391
  11. package/dist/omnish-claude/README.md +80 -0
  12. package/dist/omnish-claude/hooks/omnish-notify.py +213 -0
  13. package/dist/omnish-claude/hooks/omnish-notify.sh +13 -0
  14. package/dist/omnish-claude/install.sh +174 -0
  15. package/dist/omnish-claude/omnish-notify.json.example +8 -0
  16. package/dist/omnish-claude/scripts/doctor.sh +99 -0
  17. package/dist/omnish-claude/skill/SKILL.md +39 -0
  18. package/dist/omnish-claude/skill/files-and-sharing.md +94 -0
  19. package/dist/omnish-claude/skill/notifications.md +113 -0
  20. package/dist/omnish-claude/skill/setup-paths.md +81 -0
  21. package/dist/omnish-claude/uninstall.sh +114 -0
  22. package/dist/omnish-cursor/README.md +176 -0
  23. package/dist/omnish-cursor/hooks/__pycache__/omnish-notify.cpython-313.pyc +0 -0
  24. package/dist/omnish-cursor/hooks/omnish-notify.py +563 -0
  25. package/dist/omnish-cursor/hooks/omnish-notify.sh +13 -0
  26. package/dist/omnish-cursor/hooks/omnish-session-start.sh +48 -0
  27. package/dist/omnish-cursor/install.sh +162 -0
  28. package/dist/omnish-cursor/omnish-notify.json.example +13 -0
  29. package/dist/omnish-cursor/rules/omnish-notify.mdc +45 -0
  30. package/dist/omnish-cursor/scripts/doctor.sh +126 -0
  31. package/dist/omnish-cursor/skill/SKILL.md +129 -0
  32. package/dist/omnish-cursor/skill/files-and-sharing.md +94 -0
  33. package/dist/omnish-cursor/skill/notifications.md +155 -0
  34. package/dist/omnish-cursor/skill/setup-paths.md +81 -0
  35. package/dist/omnish-cursor/uninstall.sh +107 -0
  36. package/dist/ui/assets/{index-aUJGrxrr.js → index-BwG51a2I.js} +10 -10
  37. package/dist/ui/index.html +16 -1
  38. package/package.json +36 -28
  39. package/scripts/fix-node-pty-perms.mjs +41 -0
package/CHANGELOG.md CHANGED
@@ -7,24 +7,100 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.0.0] - 2026-06-18
11
+
12
+ ### Breaking
13
+
14
+ - **Platform routing:** unprefixed chat commands route to the **default device only**; use `>label cmd` for other hosts. Dashboard peer bindings no longer affect inbound dispatch ([docs/adr/0013-platform-device-prefix-routing.md](docs/adr/0013-platform-device-prefix-routing.md)).
15
+ - **Cluster CLI:** `omnish cluster here` removed — use chat `/c here` or `omnish cluster use <sender> <label>`.
16
+ - **Cluster chat:** `/c step-down` removed; per-sender binding via `/c unuse`.
17
+ - **`clusterRole`:** informational only; no longer gates traffic.
18
+ - **Telemetry default-on:** gateways send anonymous heartbeats unless `OMNISH_TELEMETRY=0` or `telemetryEnabled: false` ([docs/adr/0017-default-on-instance-telemetry.md](docs/adr/0017-default-on-instance-telemetry.md)).
19
+
10
20
  ### Added
11
21
 
22
+ - **Connectors:** Signal integration; OAuth link flows for Slack, Discord, and Twitch; Slack DM gateway assets.
23
+ - **Platform:** user auth (signup/login, email verification, password reset, SMTP templates); default device management; `/devices` routing commands; admin telemetry APIs and AdminView improvements.
24
+ - **Integrations:** Omnish Cursor and Claude Code install/notify paths; enhanced `omnish-notify` config.
25
+ - **Gateway:** lifecycle broadcast to allowlisted peers on startup/shutdown (with WhatsApp JID fix).
26
+ - **Cluster:** WebSocket keep-alive; attached auto-binding on inbound; enhanced cluster state handling.
27
+ - **CLI/UI:** `/apps start` flags; platform dashboard mobile nav; analytics hooks; `.nvmrc`.
28
+
29
+ ### Changed
30
+
31
+ - Connector management and user allowlist handling.
32
+ - Dependencies for expanded channel support.
33
+ - Postinstall / native module checks.
34
+
35
+ ### Fixed
36
+
37
+ - Signal QR display issue.
38
+ - AdminView fetch error handling.
39
+
40
+ [2.0.0]: https://github.com/labKnowledge/omnish/compare/v1.6.6...v2.0.0
41
+
42
+ ## [1.6.6] - 2026-05-30
43
+
44
+ ### Fixed
45
+
46
+ - **macOS npm installs:** auto-fix `node-pty` `spawn-helper` execute permission at install (`postinstall`) and before the first PTY spawn so `!commands` and interactive sessions work after `npm install -g omnish`.
47
+
48
+ ### Changed
49
+
50
+ - Pre-declare npm `allowScripts` for native dependencies (`node-pty`, `better-sqlite3`, Baileys/sharp/protobufjs, `@parcel/watcher`) to reduce npm 11+ install warnings.
51
+
52
+ [1.6.6]: https://github.com/labKnowledge/omnish/compare/v1.6.5...v1.6.6
53
+
54
+ ## [1.6.5] - 2026-05-30
55
+
56
+ ### Added
57
+
58
+ - **Chat agent daemon:** optional background agent with `chatAgentEnabled`, wrapper script, and `agent-notify` env wiring. See [docs/features/chat-agent-daemon.md](docs/features/chat-agent-daemon.md).
59
+ - **Job board coordinator (default on):** clearer status handoffs, end-of-tick supervisor review, primary agent via `/board agent`, richer list/tick feedback, live-status and file delivery via `omnish i -c sendto`, and competency docs.
12
60
  - **Dev tooling:** Prettier with root [`.prettierrc.json`](.prettierrc.json); run `pnpm format` or `pnpm format:check` before submitting PRs (CI enforces format check).
13
61
 
14
62
  ### Changed
15
63
 
16
64
  - **Documentation search (chat):** `/docs search` → **`/s q`** (shorthand **`/s`**, full form **`/search`**). List, show, and follow moved to `/s` / `/search`. Legacy **`/docs`**, **`/help search`**, and **`omnish docs`** still work. Host CLI: **`omnish search q`**.
65
+ - **`omnish start`:** start the gateway in the background by default (pairs with **`omnish stop`**). Foreground: **`omnish start -f`**. **`omnish run`** stays foreground unless **`-d`** is passed.
66
+ - **Board notifications:** easier coordinator/employee notify paths via board communication helpers.
67
+
68
+ ### Fixed
69
+
70
+ - **Board:** notification and competency wiring for coordinator workforce flows.
71
+
72
+ [1.6.5]: https://github.com/labKnowledge/omnish/compare/v1.6.4...v1.6.5
73
+
74
+ ## [1.6.4] - 2026-05-24
17
75
 
18
76
  ### Added
19
77
 
20
- - **`omnish start`:** start the gateway in the background by default (pairs with **`omnish stop`**). Foreground: **`omnish start -f`**. **`omnish run`** stays foreground unless **`-d`** is passed.
78
+ - **Digital employees / job board:** `/board` chat commands, employee harness, coordinator agent, competencies, example employee pack under `contrib/employee-pack-example/`, and guides ([docs/guides/digital-employees.md](docs/guides/digital-employees.md), [docs/features/job-board.md](docs/features/job-board.md)).
79
+ - **Shortcuts with input:** slash shortcuts can prompt for missing arguments interactively.
80
+ - **Whisper / transcribe:** transformers-backed transcribe path, config keys, and improved `/tr` / pull transcribe tooling.
21
81
 
22
- ## [1.6.2] - 2026-05-23
82
+ ### Fixed
83
+
84
+ - **Media `/edit` and transcribe:** parsing, tests, and reliability fixes for edit and transcription flows.
85
+
86
+ [1.6.4]: https://github.com/labKnowledge/omnish/compare/v1.6.3...v1.6.4
87
+
88
+ ## [1.6.3] - 2026-05-23
23
89
 
24
90
  ### Security
25
91
 
26
92
  - **Baileys:** upgrade `@whiskeysockets/baileys` from `7.0.0-rc.9` to `7.0.0-rc13` (patches CVE-2026-48063 — message spoofing / app-state corruption).
27
93
 
94
+ First **1.6.x** release on [npm](https://www.npmjs.com/package/omnish); registry skipped `1.6.0`–`1.6.2` (those versions exist only in this changelog / git history).
95
+
96
+ [1.6.3]: https://github.com/labKnowledge/omnish/compare/v1.6.1...v1.6.3
97
+
98
+ ## [1.6.2] - 2026-05-23
99
+
100
+ ### Security
101
+
102
+ - **Baileys:** same upgrade as [1.6.3] (CVE-2026-48063). Shipped to npm as **1.6.3** only.
103
+
28
104
  [1.6.2]: https://github.com/labKnowledge/omnish/compare/v1.6.1...v1.6.2
29
105
 
30
106
  ## [1.6.1] - 2026-05-23
package/README.md CHANGED
@@ -79,6 +79,12 @@ Full steps for systemd, launchd, and Task Scheduler — **[docs/guides/backgroun
79
79
 
80
80
  Run `omnish status` to see the resolved data directory and auth path.
81
81
 
82
+ ## Telemetry (default-on, opt-out)
83
+
84
+ While **`omnish run`** is active, omnish sends anonymous instance health metadata to the platform telemetry endpoint (default: `https://tunnel.omnish.dev`): install id (`~/.omnish/node-id`), omnish version, OS/arch, Node version, gateway mode, and enabled channel count. No message content, allowlists, or file paths are included.
85
+
86
+ **Opt out:** `OMNISH_TELEMETRY=0` or `omnish config set telemetryEnabled false`. Override the endpoint with `telemetryUrl` in config.
87
+
82
88
  While **`omnish run`** is active, a localhost control channel may write **`gateway-control.json`** (and a random high port on `127.0.0.1`) so **`omnish i`** can request outbound file sends.
83
89
 
84
90
  Per-chat shell cwd is in `sessions.json`; **user shortcuts** are stored in `shortcuts.json` (same data directory).
@@ -112,6 +118,10 @@ omnish run
112
118
 
113
119
  **Single phone:** omnish runs on a PC or server; you link it like WhatsApp Web (one QR scan on your phone). See [Quick start — One phone with WhatsApp](docs/guides/quick-start.md#one-phone-with-whatsapp).
114
120
 
121
+ **npm 11+ install warnings:** You may see advisory `allow-scripts` notices for native dependencies (`node-pty`, `better-sqlite3`, etc.). Install still succeeds; omnish pre-declares these in `allowScripts`. The `prebuild-install` deprecation warning comes from upstream native modules and is harmless.
122
+
123
+ **macOS:** `node-pty` ships `spawn-helper` without the execute bit in its npm tarball ([upstream issue](https://github.com/microsoft/node-pty/issues/850)). omnish fixes this at install (`postinstall`) and before the first shell command. If `!commands` fail with `posix_spawnp failed` on an older install, update omnish or run `chmod +x "$(npm root -g)/omnish/node_modules/node-pty/prebuilds/darwin-"*"/spawn-helper"`.
124
+
115
125
  Native modules (for example **`node-pty`**) may compile on install. If postinstall scripts were skipped, enable them for this package and reinstall.
116
126
 
117
127
  ## Quick setup (from source)
@@ -153,24 +163,24 @@ Output is **debounced** (`appsFlushMs`, default 300 ms), **throttled** (`appsMin
153
163
 
154
164
  ### `/apps` cheat sheet
155
165
 
156
- | Command | Action |
157
- | ------------------------------------------- | ----------------------------------------------------------------------------- |
158
- | `/apps start <name> <cmd…>` | Spawn app session in session cwd; **auto-attaches** `<name>`. |
159
- | `/apps attach <name>` | Focus plain DMs on that running session. |
160
- | `/apps detach` | Clear focus. |
161
- | `/apps list` | Sessions for this chat; `*` marks focus. Shows `attached: …` or `(no focus)`. |
162
- | `/apps info <name>` / `/apps get <name>` | Cmd, cwd, env key count, terminal size, ring bytes, log path/size, mute/raw. |
163
- | `/apps send <name> <text>` | Write `text` + newline (no attach). |
164
- | `>name text` | Same as `/apps send`. |
165
- | `/apps key <name> KEY[,KEY…]` | Special keys: `Enter`, `Tab`, `Esc`, arrows, `^C`, `ctrl+d`, `\x1b`, … |
166
- | `/apps tail <name> [lines]` | Last _lines_ of log (default `appsLogTailLines`). |
167
- | `/apps since <name>` | New log bytes since your last `/apps since` for that name. |
168
- | `/apps mute <name>` / `/apps unmute <name>` | Pause / resume streaming to the chat (log still grows). |
169
- | `/apps raw <name> on\|off` | Keep ANSI in streamed messages when `on`. |
170
- | `/apps resize <name> <cols> <rows>` | Resize terminal. |
171
- | `/apps stop <name>` | SIGTERM; SIGKILL after 5 s if still alive. |
172
- | `/apps kill <name>` | SIGKILL immediately. |
173
- | `/apps rm <name>` | Only after the process has **exited**; removes metadata + log file. |
166
+ | Command | Action |
167
+ | --------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
168
+ | `/apps start <name> [--mute\|-mute\|--detach\|-d] <cmd…>` | Spawn in session cwd; **auto-attaches** unless `--detach`; `--mute` skips chat streaming. |
169
+ | `/apps attach <name>` | Focus plain DMs on that running session. |
170
+ | `/apps detach` | Clear focus. |
171
+ | `/apps list` | Sessions for this chat; `*` marks focus. Shows `attached: …` or `(no focus)`. |
172
+ | `/apps info <name>` / `/apps get <name>` | Cmd, cwd, env key count, terminal size, ring bytes, log path/size, mute/raw. |
173
+ | `/apps send <name> <text>` | Write `text` + newline (no attach). |
174
+ | `>name text` | Same as `/apps send`. |
175
+ | `/apps key <name> KEY[,KEY…]` | Special keys: `Enter`, `Tab`, `Esc`, arrows, `^C`, `ctrl+d`, `\x1b`, … |
176
+ | `/apps tail <name> [lines]` | Last _lines_ of log (default `appsLogTailLines`). |
177
+ | `/apps since <name>` | New log bytes since your last `/apps since` for that name. |
178
+ | `/apps mute <name>` / `/apps unmute <name>` | Pause / resume streaming to the chat (log still grows). |
179
+ | `/apps raw <name> on\|off` | Keep ANSI in streamed messages when `on`. |
180
+ | `/apps resize <name> <cols> <rows>` | Resize terminal. |
181
+ | `/apps stop <name>` | SIGTERM; SIGKILL after 5 s if still alive. |
182
+ | `/apps kill <name>` | SIGKILL immediately. |
183
+ | `/apps rm <name>` | Only after the process has **exited**; removes metadata + log file. |
174
184
 
175
185
  To send a literal `!`, `/`, or `>` to the attached program, use **`/apps send <name> …`** or **`>name …`**.
176
186
 
@@ -262,6 +272,8 @@ Index and curated paths: **[docs/README.md](docs/README.md)**.
262
272
  | Documentation search (`/s`, `omnish search`) | [docs/features/docs-search-from-chat.md](docs/features/docs-search-from-chat.md) |
263
273
  | System agents + `/run` | [docs/guides/system-agents-and-run.md](docs/guides/system-agents-and-run.md) |
264
274
  | MCP IDE spike (experimental) | [contrib/mcp-spike/README.md](contrib/mcp-spike/README.md) |
275
+ | Cursor integration (hooks + skill) | [contrib/omnish-cursor/README.md](contrib/omnish-cursor/README.md) |
276
+ | Claude Code integration (hooks + skill) | [contrib/omnish-claude/README.md](contrib/omnish-claude/README.md) |
265
277
  | Telegram | [docs/telegram-integration-notes.md](docs/telegram-integration-notes.md) |
266
278
  | Send/receive files (`/send` selectors, `/sendto` destinations) | [docs/files-send-receive.md](docs/files-send-receive.md) |
267
279
  | Troubleshooting | [docs/advanced/troubleshooting.md](docs/advanced/troubleshooting.md) |
@@ -38,6 +38,7 @@
38
38
  "clusterRole": "secondary",
39
39
  "clusterSenderBindings": {},
40
40
  "serviceInstallFromChat": false,
41
+ "agentInstallFromChat": false,
41
42
  "updateCheckEnabled": false,
42
43
  "updateCheckIntervalMs": 86400000,
43
44
  "updateCheckPackageName": "omnish",
@@ -0,0 +1,174 @@
1
+ #!/usr/bin/env bash
2
+ # Install Omnish Claude Code bundle: Stop hook + skill into ~/.claude
3
+ set -euo pipefail
4
+
5
+ OMNISH_CLAUDE_BUNDLE_URL="${OMNISH_CLAUDE_BUNDLE_URL:-https://omnish.dev/downloads/omnish-claude.tar.gz}"
6
+ _TMP_BUNDLE_DIR=""
7
+
8
+ need() {
9
+ command -v "$1" >/dev/null 2>&1 || {
10
+ echo "error: required command not found: $1" >&2
11
+ exit 1
12
+ }
13
+ }
14
+
15
+ cleanup() {
16
+ if [[ -n "$_TMP_BUNDLE_DIR" && -d "$_TMP_BUNDLE_DIR" ]]; then
17
+ rm -rf "$_TMP_BUNDLE_DIR"
18
+ fi
19
+ }
20
+
21
+ _SCRIPT="${BASH_SOURCE[0]:-}"
22
+ if [[ -n "$_SCRIPT" && -f "$_SCRIPT" ]]; then
23
+ ROOT="$(cd "$(dirname "$_SCRIPT")" && pwd)"
24
+ else
25
+ need curl
26
+ need tar
27
+ _TMP_BUNDLE_DIR="$(mktemp -d "${TMPDIR:-/tmp}/omnish-claude.XXXXXX")"
28
+ trap cleanup EXIT
29
+ echo "Downloading Omnish Claude Code bundle..." >&2
30
+ curl -fsSL "$OMNISH_CLAUDE_BUNDLE_URL" | tar -xzf - -C "$_TMP_BUNDLE_DIR"
31
+ if [[ ! -d "$_TMP_BUNDLE_DIR/omnish-claude" ]]; then
32
+ echo "error: bundle missing omnish-claude/ top-level directory" >&2
33
+ exit 1
34
+ fi
35
+ ROOT="$_TMP_BUNDLE_DIR/omnish-claude"
36
+ fi
37
+
38
+ CLAUDE_DIR="${CLAUDE_DIR:-$HOME/.claude}"
39
+ HOOKS_DIR="$CLAUDE_DIR/hooks"
40
+ SKILL_DIR="$CLAUDE_DIR/skills/omnish"
41
+ SETTINGS_JSON="$CLAUDE_DIR/settings.json"
42
+ HOOK_CMD="$HOOKS_DIR/omnish-notify.sh"
43
+
44
+ INSTALL_HOOKS=1
45
+ INSTALL_SKILL=1
46
+
47
+ usage() {
48
+ cat <<EOF
49
+ Usage: $(basename "$0") [options]
50
+
51
+ Install Omnish Claude Code integration (Stop hook, skill, notify config).
52
+
53
+ Options:
54
+ --hooks-only Install only Stop hook + notify config
55
+ --skill-only Install only the omnish Claude skill (+ doctor script)
56
+ -h, --help Show this help
57
+ EOF
58
+ }
59
+
60
+ while [[ $# -gt 0 ]]; do
61
+ case "$1" in
62
+ --hooks-only)
63
+ INSTALL_HOOKS=1
64
+ INSTALL_SKILL=0
65
+ shift
66
+ ;;
67
+ --skill-only)
68
+ INSTALL_HOOKS=0
69
+ INSTALL_SKILL=1
70
+ shift
71
+ ;;
72
+ -h | --help)
73
+ usage
74
+ exit 0
75
+ ;;
76
+ *)
77
+ echo "error: unknown option: $1" >&2
78
+ usage >&2
79
+ exit 1
80
+ ;;
81
+ esac
82
+ done
83
+
84
+ if [[ "$INSTALL_HOOKS" -eq 1 ]]; then
85
+ need python3
86
+ need omnish
87
+ fi
88
+
89
+ if [[ "$INSTALL_HOOKS" -eq 1 ]]; then
90
+ mkdir -p "$HOOKS_DIR"
91
+
92
+ install -m 755 "$ROOT/hooks/omnish-notify.sh" "$HOOKS_DIR/omnish-notify.sh"
93
+ install -m 644 "$ROOT/hooks/omnish-notify.py" "$HOOKS_DIR/omnish-notify.py"
94
+
95
+ if [[ ! -f "$CLAUDE_DIR/omnish-notify.json" ]]; then
96
+ install -m 644 "$ROOT/omnish-notify.json.example" "$CLAUDE_DIR/omnish-notify.json"
97
+ echo "created $CLAUDE_DIR/omnish-notify.json"
98
+ else
99
+ echo "kept existing $CLAUDE_DIR/omnish-notify.json"
100
+ fi
101
+
102
+ python3 - "$SETTINGS_JSON" "$HOOK_CMD" <<'PY'
103
+ import json
104
+ import sys
105
+ from pathlib import Path
106
+
107
+ settings_path = Path(sys.argv[1])
108
+ hook_cmd = sys.argv[2]
109
+ entry = {
110
+ "hooks": [
111
+ {
112
+ "type": "command",
113
+ "command": hook_cmd,
114
+ }
115
+ ]
116
+ }
117
+
118
+ if settings_path.exists():
119
+ try:
120
+ data = json.loads(settings_path.read_text(encoding="utf-8"))
121
+ except json.JSONDecodeError:
122
+ data = {}
123
+ else:
124
+ data = {}
125
+
126
+ hooks = data.setdefault("hooks", {})
127
+ existing = hooks.get("Stop") or []
128
+ if not isinstance(existing, list):
129
+ existing = []
130
+
131
+ found = False
132
+ for group in existing:
133
+ if not isinstance(group, dict):
134
+ continue
135
+ inner = group.get("hooks") or []
136
+ if any(isinstance(h, dict) and h.get("command") == hook_cmd for h in inner):
137
+ found = True
138
+ break
139
+
140
+ if not found:
141
+ existing.append(entry)
142
+ hooks["Stop"] = existing
143
+ settings_path.parent.mkdir(parents=True, exist_ok=True)
144
+ settings_path.write_text(json.dumps(data, indent=2) + "\n", encoding="utf-8")
145
+ print(f"updated {settings_path} (added Stop hook)")
146
+ else:
147
+ print(f"Stop hook already registered in {settings_path}")
148
+ PY
149
+ fi
150
+
151
+ if [[ "$INSTALL_SKILL" -eq 1 ]]; then
152
+ mkdir -p "$SKILL_DIR/scripts"
153
+ install -m 644 "$ROOT/skill/SKILL.md" "$SKILL_DIR/SKILL.md"
154
+ install -m 644 "$ROOT/skill/setup-paths.md" "$SKILL_DIR/setup-paths.md"
155
+ install -m 644 "$ROOT/skill/files-and-sharing.md" "$SKILL_DIR/files-and-sharing.md"
156
+ install -m 644 "$ROOT/skill/notifications.md" "$SKILL_DIR/notifications.md"
157
+ install -m 755 "$ROOT/scripts/doctor.sh" "$SKILL_DIR/scripts/doctor.sh"
158
+ echo "installed skill to $SKILL_DIR"
159
+ fi
160
+
161
+ cat <<EOF
162
+
163
+ Installed Omnish Claude Code bundle.
164
+
165
+ Next steps:
166
+ 1. Ensure omnish gateway is running: omnish run
167
+ 2. Platform attached: omnish config show platform
168
+ Local mode: omnish link && omnish allow +E164 (or tg:id)
169
+ 3. Restart Claude Code (hooks reload from settings.json)
170
+ 4. Run: bash $SKILL_DIR/scripts/doctor.sh
171
+
172
+ Config: $CLAUDE_DIR/omnish-notify.json
173
+ Default peer: * (all allowlisted contacts)
174
+ EOF
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env bash
2
+ # Remove Omnish Claude Code bundle entries from ~/.claude (keeps unrelated hooks).
3
+ set -euo pipefail
4
+
5
+ CLAUDE_DIR="${CLAUDE_DIR:-$HOME/.claude}"
6
+ SETTINGS_JSON="$CLAUDE_DIR/settings.json"
7
+ HOOK_CMD="$CLAUDE_DIR/hooks/omnish-notify.sh"
8
+
9
+ REMOVE_HOOKS=1
10
+ REMOVE_SKILL=1
11
+ REMOVE_CONFIG=0
12
+
13
+ usage() {
14
+ cat <<EOF
15
+ Usage: $(basename "$0") [options]
16
+
17
+ Remove Omnish Claude Code integration installed by install.sh.
18
+
19
+ Options:
20
+ --hooks-only Remove Stop hook + hook scripts only
21
+ --skill-only Remove ~/.claude/skills/omnish only
22
+ --with-config Also delete ~/.claude/omnish-notify.json
23
+ -h, --help Show this help
24
+ EOF
25
+ }
26
+
27
+ while [[ $# -gt 0 ]]; do
28
+ case "$1" in
29
+ --hooks-only)
30
+ REMOVE_HOOKS=1
31
+ REMOVE_SKILL=0
32
+ shift
33
+ ;;
34
+ --skill-only)
35
+ REMOVE_HOOKS=0
36
+ REMOVE_SKILL=1
37
+ shift
38
+ ;;
39
+ --with-config)
40
+ REMOVE_CONFIG=1
41
+ shift
42
+ ;;
43
+ -h | --help)
44
+ usage
45
+ exit 0
46
+ ;;
47
+ *)
48
+ echo "error: unknown option: $1" >&2
49
+ usage >&2
50
+ exit 1
51
+ ;;
52
+ esac
53
+ done
54
+
55
+ if [[ "$REMOVE_HOOKS" -eq 1 && -f "$SETTINGS_JSON" ]]; then
56
+ python3 - "$SETTINGS_JSON" "$HOOK_CMD" <<'PY'
57
+ import json
58
+ import sys
59
+ from pathlib import Path
60
+
61
+ settings_path = Path(sys.argv[1])
62
+ hook_cmd = sys.argv[2]
63
+ if not settings_path.is_file():
64
+ raise SystemExit(0)
65
+ data = json.loads(settings_path.read_text(encoding="utf-8"))
66
+ hooks = data.get("hooks") or {}
67
+ existing = hooks.get("Stop") or []
68
+ if not isinstance(existing, list):
69
+ raise SystemExit(0)
70
+ filtered = []
71
+ changed = False
72
+ for group in existing:
73
+ if not isinstance(group, dict):
74
+ filtered.append(group)
75
+ continue
76
+ inner = group.get("hooks") or []
77
+ new_inner = [
78
+ h for h in inner
79
+ if not (isinstance(h, dict) and h.get("command") == hook_cmd)
80
+ ]
81
+ if len(new_inner) != len(inner):
82
+ changed = True
83
+ if new_inner:
84
+ group = dict(group)
85
+ group["hooks"] = new_inner
86
+ filtered.append(group)
87
+ if changed:
88
+ if filtered:
89
+ hooks["Stop"] = filtered
90
+ else:
91
+ hooks.pop("Stop", None)
92
+ settings_path.write_text(json.dumps(data, indent=2) + "\n", encoding="utf-8")
93
+ print(f"updated {settings_path} (removed omnish Stop hook)")
94
+ else:
95
+ print(f"no omnish Stop hook in {settings_path}")
96
+ PY
97
+ fi
98
+
99
+ if [[ "$REMOVE_HOOKS" -eq 1 ]]; then
100
+ rm -f "$CLAUDE_DIR/hooks/omnish-notify.sh" "$CLAUDE_DIR/hooks/omnish-notify.py"
101
+ echo "removed hook scripts"
102
+ fi
103
+
104
+ if [[ "$REMOVE_SKILL" -eq 1 ]]; then
105
+ rm -rf "$CLAUDE_DIR/skills/omnish"
106
+ echo "removed $CLAUDE_DIR/skills/omnish"
107
+ fi
108
+
109
+ if [[ "$REMOVE_CONFIG" -eq 1 ]]; then
110
+ rm -f "$CLAUDE_DIR/omnish-notify.json"
111
+ echo "removed $CLAUDE_DIR/omnish-notify.json"
112
+ fi
113
+
114
+ echo "Done. Restart Claude Code if hooks were removed."
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/env bash
2
+ # Install Omnish Cursor bundle: hooks + skill + rule into ~/.cursor
3
+ set -euo pipefail
4
+
5
+ OMNISH_CURSOR_BUNDLE_URL="${OMNISH_CURSOR_BUNDLE_URL:-https://omnish.dev/downloads/omnish-cursor.tar.gz}"
6
+ _TMP_BUNDLE_DIR=""
7
+
8
+ need() {
9
+ command -v "$1" >/dev/null 2>&1 || {
10
+ echo "error: required command not found: $1" >&2
11
+ exit 1
12
+ }
13
+ }
14
+
15
+ cleanup() {
16
+ if [[ -n "$_TMP_BUNDLE_DIR" && -d "$_TMP_BUNDLE_DIR" ]]; then
17
+ rm -rf "$_TMP_BUNDLE_DIR"
18
+ fi
19
+ }
20
+
21
+ _SCRIPT="${BASH_SOURCE[0]:-}"
22
+ if [[ -n "$_SCRIPT" && -f "$_SCRIPT" ]]; then
23
+ ROOT="$(cd "$(dirname "$_SCRIPT")" && pwd)"
24
+ else
25
+ need curl
26
+ need tar
27
+ _TMP_BUNDLE_DIR="$(mktemp -d "${TMPDIR:-/tmp}/omnish-cursor.XXXXXX")"
28
+ trap cleanup EXIT
29
+ echo "Downloading Omnish Cursor bundle..." >&2
30
+ curl -fsSL "$OMNISH_CURSOR_BUNDLE_URL" | tar -xzf - -C "$_TMP_BUNDLE_DIR"
31
+ if [[ ! -d "$_TMP_BUNDLE_DIR/omnish-cursor" ]]; then
32
+ echo "error: bundle missing omnish-cursor/ top-level directory" >&2
33
+ exit 1
34
+ fi
35
+ ROOT="$_TMP_BUNDLE_DIR/omnish-cursor"
36
+ fi
37
+
38
+ CURSOR_DIR="${CURSOR_DIR:-$HOME/.cursor}"
39
+ HOOKS_DIR="$CURSOR_DIR/hooks"
40
+ RULES_DIR="$CURSOR_DIR/rules"
41
+ SKILL_DIR="$CURSOR_DIR/skills/omnish"
42
+
43
+ INSTALL_HOOKS=1
44
+ INSTALL_SKILL=1
45
+
46
+ usage() {
47
+ cat <<EOF
48
+ Usage: $(basename "$0") [options]
49
+
50
+ Install Omnish Cursor integration (hooks, skill, rule, config).
51
+
52
+ Options:
53
+ --hooks-only Install only Cursor hooks + rule + notify config
54
+ --skill-only Install only the omnish Cursor skill (+ doctor script)
55
+ -h, --help Show this help
56
+ EOF
57
+ }
58
+
59
+ while [[ $# -gt 0 ]]; do
60
+ case "$1" in
61
+ --hooks-only)
62
+ INSTALL_HOOKS=1
63
+ INSTALL_SKILL=0
64
+ shift
65
+ ;;
66
+ --skill-only)
67
+ INSTALL_HOOKS=0
68
+ INSTALL_SKILL=1
69
+ shift
70
+ ;;
71
+ -h | --help)
72
+ usage
73
+ exit 0
74
+ ;;
75
+ *)
76
+ echo "error: unknown option: $1" >&2
77
+ usage >&2
78
+ exit 1
79
+ ;;
80
+ esac
81
+ done
82
+
83
+ if [[ "$INSTALL_HOOKS" -eq 1 ]]; then
84
+ need python3
85
+ need omnish
86
+ fi
87
+
88
+ if [[ "$INSTALL_HOOKS" -eq 1 ]]; then
89
+ mkdir -p "$HOOKS_DIR" "$RULES_DIR"
90
+
91
+ install -m 755 "$ROOT/hooks/omnish-notify.sh" "$HOOKS_DIR/omnish-notify.sh"
92
+ install -m 755 "$ROOT/hooks/omnish-session-start.sh" "$HOOKS_DIR/omnish-session-start.sh"
93
+ install -m 644 "$ROOT/hooks/omnish-notify.py" "$HOOKS_DIR/omnish-notify.py"
94
+ install -m 644 "$ROOT/rules/omnish-notify.mdc" "$RULES_DIR/omnish-notify.mdc"
95
+
96
+ if [[ ! -f "$CURSOR_DIR/omnish-notify.json" ]]; then
97
+ install -m 644 "$ROOT/omnish-notify.json.example" "$CURSOR_DIR/omnish-notify.json"
98
+ echo "created $CURSOR_DIR/omnish-notify.json"
99
+ else
100
+ echo "kept existing $CURSOR_DIR/omnish-notify.json"
101
+ fi
102
+
103
+ python3 - "$CURSOR_DIR/hooks.json" <<'PY'
104
+ import json
105
+ import sys
106
+ from pathlib import Path
107
+
108
+ hooks_path = Path(sys.argv[1])
109
+ desired = {
110
+ "sessionStart": [{"command": "./hooks/omnish-session-start.sh"}],
111
+ "stop": [{"command": "./hooks/omnish-notify.sh"}],
112
+ }
113
+
114
+ if hooks_path.exists():
115
+ try:
116
+ data = json.loads(hooks_path.read_text(encoding="utf-8"))
117
+ except json.JSONDecodeError:
118
+ data = {"version": 1, "hooks": {}}
119
+ else:
120
+ data = {"version": 1, "hooks": {}}
121
+
122
+ data.setdefault("version", 1)
123
+ hooks = data.setdefault("hooks", {})
124
+
125
+ for event, entries in desired.items():
126
+ existing = hooks.get(event) or []
127
+ commands = {entry.get("command") for entry in existing if isinstance(entry, dict)}
128
+ merged = list(existing)
129
+ for entry in entries:
130
+ if entry["command"] not in commands:
131
+ merged.append(entry)
132
+ hooks[event] = merged
133
+
134
+ hooks_path.write_text(json.dumps(data, indent=2) + "\n", encoding="utf-8")
135
+ print(f"updated {hooks_path}")
136
+ PY
137
+ fi
138
+
139
+ if [[ "$INSTALL_SKILL" -eq 1 ]]; then
140
+ mkdir -p "$SKILL_DIR/scripts"
141
+ install -m 644 "$ROOT/skill/SKILL.md" "$SKILL_DIR/SKILL.md"
142
+ install -m 644 "$ROOT/skill/setup-paths.md" "$SKILL_DIR/setup-paths.md"
143
+ install -m 644 "$ROOT/skill/files-and-sharing.md" "$SKILL_DIR/files-and-sharing.md"
144
+ install -m 644 "$ROOT/skill/notifications.md" "$SKILL_DIR/notifications.md"
145
+ install -m 755 "$ROOT/scripts/doctor.sh" "$SKILL_DIR/scripts/doctor.sh"
146
+ echo "installed skill to $SKILL_DIR"
147
+ fi
148
+
149
+ cat <<EOF
150
+
151
+ Installed Omnish Cursor bundle.
152
+
153
+ Next steps:
154
+ 1. Ensure omnish gateway is running: omnish run
155
+ 2. Platform attached: omnish config show platform
156
+ Local mode: omnish link && omnish allow +E164 (or tg:id)
157
+ 3. Restart Cursor (or reload Hooks in Settings)
158
+ 4. Run: bash $SKILL_DIR/scripts/doctor.sh
159
+
160
+ Config: $CURSOR_DIR/omnish-notify.json
161
+ Default peer: * (all allowlisted contacts)
162
+ EOF