@ao_zorin/zocket 1.1.0 → 1.3.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.
@@ -4,34 +4,34 @@ set -euo pipefail
4
4
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
5
  REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
6
6
 
7
- SOURCE_MODE="${SOURCE_MODE:-auto}" # auto|local|git|pypi
8
- REPO_URL="${REPO_URL:-https://github.com/your-org/zocket.git}"
7
+ SOURCE_MODE="${SOURCE_MODE:-auto}" # auto|local|git|npm
8
+ REPO_URL="${REPO_URL:-https://github.com/aozorin/zocket.git}"
9
9
  REPO_REF="${REPO_REF:-main}"
10
- INSTALL_ROOT="${INSTALL_ROOT:-$HOME/.local/share/zocket}"
11
10
  ZOCKET_HOME_DIR="${ZOCKET_HOME_DIR:-$HOME/.zocket}"
12
- LANGUAGE="${LANGUAGE:-en}" # en|ru
11
+ LANGUAGE="${LANGUAGE:-en}" # en|ru (used by UI; config set via web)
13
12
  WEB_PORT="${WEB_PORT:-18001}"
14
13
  MCP_PORT="${MCP_PORT:-18002}"
15
14
  MCP_STREAM_PORT="${MCP_STREAM_PORT:-18003}"
16
- MCP_MODE="${MCP_MODE:-metadata}" # metadata|admin
15
+ MCP_MODE="${MCP_MODE:-admin}" # metadata|admin
17
16
  AUTOSTART="${AUTOSTART:-user}" # user|system|none
18
17
  SERVICE_USER="${SERVICE_USER:-zocketd}"
18
+ WEB_ENABLED="${WEB_ENABLED:-true}"
19
19
 
20
20
  usage() {
21
21
  cat <<EOF
22
22
  Usage: $(basename "$0") [options]
23
23
 
24
24
  Options:
25
- --source <auto|local|git|pypi>
25
+ --source <auto|local|git|npm>
26
26
  --repo-url <git-url>
27
27
  --repo-ref <branch-or-tag>
28
- --install-root <path>
29
28
  --zocket-home <path>
30
29
  --lang <en|ru>
31
30
  --web-port <port>
32
31
  --mcp-port <port>
33
32
  --mcp-stream-port <port>
34
33
  --mcp-mode <metadata|admin>
34
+ --no-web
35
35
  --autostart <user|system|none>
36
36
  --service-user <name>
37
37
  -h, --help
@@ -45,13 +45,13 @@ while [[ $# -gt 0 ]]; do
45
45
  --source) SOURCE_MODE="$2"; shift 2 ;;
46
46
  --repo-url) REPO_URL="$2"; shift 2 ;;
47
47
  --repo-ref) REPO_REF="$2"; shift 2 ;;
48
- --install-root) INSTALL_ROOT="$2"; shift 2 ;;
49
48
  --zocket-home) ZOCKET_HOME_DIR="$2"; shift 2 ;;
50
49
  --lang) LANGUAGE="$2"; shift 2 ;;
51
50
  --web-port) WEB_PORT="$2"; shift 2 ;;
52
51
  --mcp-port) MCP_PORT="$2"; shift 2 ;;
53
52
  --mcp-stream-port) MCP_STREAM_PORT="$2"; shift 2 ;;
54
53
  --mcp-mode) MCP_MODE="$2"; shift 2 ;;
54
+ --no-web) WEB_ENABLED="false"; shift 1 ;;
55
55
  --autostart) AUTOSTART="$2"; shift 2 ;;
56
56
  --service-user) SERVICE_USER="$2"; shift 2 ;;
57
57
  -h|--help) usage; exit 0 ;;
@@ -71,54 +71,100 @@ run_sudo() {
71
71
  fi
72
72
  }
73
73
 
74
- install_python_linux() {
74
+ install_node_linux() {
75
75
  if have_cmd apt-get; then
76
76
  run_sudo apt-get update
77
- run_sudo apt-get install -y python3 python3-venv python3-pip git curl
77
+ run_sudo apt-get install -y nodejs npm git curl
78
78
  return
79
79
  fi
80
80
  if have_cmd dnf; then
81
- run_sudo dnf install -y python3 python3-pip python3-virtualenv git curl
81
+ run_sudo dnf install -y nodejs npm git curl
82
82
  return
83
83
  fi
84
84
  if have_cmd yum; then
85
- run_sudo yum install -y python3 python3-pip git curl
85
+ run_sudo yum install -y nodejs npm git curl
86
86
  return
87
87
  fi
88
88
  if have_cmd pacman; then
89
- run_sudo pacman -Sy --noconfirm python python-pip git curl
89
+ run_sudo pacman -Sy --noconfirm nodejs npm git curl
90
90
  return
91
91
  fi
92
92
  if have_cmd zypper; then
93
- run_sudo zypper install -y python3 python3-pip python3-virtualenv git curl
93
+ run_sudo zypper install -y nodejs npm git curl
94
94
  return
95
95
  fi
96
96
  if have_cmd apk; then
97
- run_sudo apk add --no-cache python3 py3-pip py3-virtualenv git curl
97
+ run_sudo apk add --no-cache nodejs npm git curl
98
98
  return
99
99
  fi
100
- echo "Unsupported Linux package manager. Install Python 3.10+, pip, and venv manually." >&2
100
+ echo "Unsupported Linux package manager. Install Node.js 18+ and npm manually." >&2
101
101
  exit 1
102
102
  }
103
103
 
104
- install_python_macos() {
104
+ install_node_macos() {
105
105
  if ! have_cmd brew; then
106
106
  echo "Homebrew not found. Install Homebrew first: https://brew.sh" >&2
107
107
  exit 1
108
108
  fi
109
- brew install python git curl
109
+ brew install node git curl
110
110
  }
111
111
 
112
+ OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
113
+ if ! have_cmd node || ! have_cmd npm; then
114
+ echo "node/npm not found, installing dependencies..."
115
+ case "$OS" in
116
+ linux*) install_node_linux ;;
117
+ darwin*) install_node_macos ;;
118
+ *)
119
+ echo "Unsupported OS for this installer: $OS" >&2
120
+ exit 1
121
+ ;;
122
+ esac
123
+ fi
124
+
125
+ if [[ "$SOURCE_MODE" == "auto" ]]; then
126
+ if [[ -f "${REPO_ROOT}/package.json" ]]; then
127
+ SOURCE_MODE="local"
128
+ else
129
+ SOURCE_MODE="npm"
130
+ fi
131
+ fi
132
+
133
+ case "$SOURCE_MODE" in
134
+ local)
135
+ npm i -g "${REPO_ROOT}"
136
+ ;;
137
+ git)
138
+ npm i -g "git+${REPO_URL}#${REPO_REF}"
139
+ ;;
140
+ npm)
141
+ npm i -g @ao_zorin/zocket
142
+ ;;
143
+ *)
144
+ echo "Invalid source mode: $SOURCE_MODE" >&2
145
+ exit 2
146
+ ;;
147
+ esac
148
+
149
+ ZOCKET_BIN="$(command -v zocket || true)"
150
+ if [[ -z "${ZOCKET_BIN}" ]]; then
151
+ echo "zocket binary not found after install" >&2
152
+ exit 1
153
+ fi
154
+
155
+ export ZOCKET_HOME="${ZOCKET_HOME_DIR}"
156
+ mkdir -p "${ZOCKET_HOME_DIR}"
157
+ "${ZOCKET_BIN}" init >/dev/null
158
+
112
159
  write_systemd_unit() {
113
160
  local unit_path="$1"
114
161
  local exec_start="$2"
115
162
  local svc_user="$3"
116
163
  local svc_group="$4"
117
164
  local zocket_home="$5"
118
- local extra_rw="${6:-}"
119
165
  run_sudo tee "${unit_path}" >/dev/null <<EOF
120
166
  [Unit]
121
- Description=Zocket $(basename "${unit_path%.service}")
167
+ Description=Zocket service
122
168
  After=network-online.target
123
169
  Wants=network-online.target
124
170
 
@@ -138,7 +184,7 @@ ProtectKernelTunables=true
138
184
  ProtectControlGroups=true
139
185
  LockPersonality=true
140
186
  MemoryDenyWriteExecute=true
141
- ReadWritePaths=${zocket_home} ${extra_rw}
187
+ ReadWritePaths=${zocket_home}
142
188
 
143
189
  [Install]
144
190
  WantedBy=multi-user.target
@@ -152,7 +198,7 @@ write_systemd_user_unit() {
152
198
  mkdir -p "$(dirname "${unit_path}")"
153
199
  cat > "${unit_path}" <<EOF
154
200
  [Unit]
155
- Description=Zocket $(basename "${unit_path%.service}")
201
+ Description=Zocket service
156
202
  After=default.target
157
203
 
158
204
  [Service]
@@ -198,149 +244,42 @@ EOF
198
244
  EOF
199
245
  }
200
246
 
201
- OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
202
- if ! have_cmd python3; then
203
- echo "python3 not found, installing dependencies..."
204
- case "$OS" in
205
- linux*) install_python_linux ;;
206
- darwin*) install_python_macos ;;
207
- *)
208
- echo "Unsupported OS for this installer: $OS" >&2
209
- exit 1
210
- ;;
211
- esac
247
+ EXEC_START="${ZOCKET_BIN} start --host 127.0.0.1 --web-port ${WEB_PORT} --mcp-port ${MCP_PORT} --mcp-stream-port ${MCP_STREAM_PORT} --mode ${MCP_MODE}"
248
+ if [[ "$WEB_ENABLED" == "false" ]]; then
249
+ EXEC_START="${EXEC_START} --no-web"
212
250
  fi
213
251
 
214
- if ! have_cmd git; then
215
- echo "git not found, installing..."
216
- case "$OS" in
217
- linux*) install_python_linux ;;
218
- darwin*) install_python_macos ;;
219
- *) echo "Install git manually and rerun." >&2; exit 1 ;;
220
- esac
221
- fi
222
-
223
- if [[ "$SOURCE_MODE" == "auto" ]]; then
224
- if [[ -f "${REPO_ROOT}/pyproject.toml" ]]; then
225
- SOURCE_MODE="local"
226
- else
227
- SOURCE_MODE="git"
228
- fi
229
- fi
230
-
231
- PKG_SOURCE=""
232
- SRC_DIR="${INSTALL_ROOT}/src"
233
-
234
- mkdir -p "${INSTALL_ROOT}"
235
-
236
- if [[ "$SOURCE_MODE" == "local" ]]; then
237
- PKG_SOURCE="${REPO_ROOT}"
238
- elif [[ "$SOURCE_MODE" == "git" ]]; then
239
- if [[ -d "${SRC_DIR}/.git" ]]; then
240
- git -C "${SRC_DIR}" fetch --all --tags
241
- git -C "${SRC_DIR}" checkout "${REPO_REF}"
242
- git -C "${SRC_DIR}" pull --ff-only
243
- else
244
- rm -rf "${SRC_DIR}"
245
- git clone --depth 1 --branch "${REPO_REF}" "${REPO_URL}" "${SRC_DIR}"
246
- fi
247
- PKG_SOURCE="${SRC_DIR}"
248
- elif [[ "$SOURCE_MODE" == "pypi" ]]; then
249
- PKG_SOURCE="zocket"
250
- else
251
- echo "Invalid source mode: $SOURCE_MODE" >&2
252
- exit 2
253
- fi
254
-
255
- VENV_DIR="${INSTALL_ROOT}/venv"
256
- PY_BIN="${VENV_DIR}/bin/python3"
257
- ZOCKET_BIN="${VENV_DIR}/bin/zocket"
258
-
259
- python3 -m venv "${VENV_DIR}"
260
- "${PY_BIN}" -m pip install --upgrade pip setuptools wheel
261
-
262
- if [[ "$SOURCE_MODE" == "pypi" ]]; then
263
- "${PY_BIN}" -m pip install --upgrade "${PKG_SOURCE}"
264
- else
265
- "${PY_BIN}" -m pip install --upgrade "${PKG_SOURCE}"
266
- fi
267
-
268
- mkdir -p "$HOME/.local/bin"
269
- ln -sf "${ZOCKET_BIN}" "$HOME/.local/bin/zocket"
270
-
271
- export ZOCKET_HOME="${ZOCKET_HOME_DIR}"
272
- mkdir -p "${ZOCKET_HOME_DIR}"
273
-
274
- if [[ ! -f "${ZOCKET_HOME_DIR}/vault.enc" ]]; then
275
- "${ZOCKET_BIN}" init
276
- fi
277
-
278
- "${ZOCKET_BIN}" config set-language "${LANGUAGE}" >/dev/null
279
-
280
252
  if [[ "$AUTOSTART" == "user" && "$OS" == linux* ]]; then
281
253
  USER_UNIT_DIR="$HOME/.config/systemd/user"
282
- write_systemd_user_unit "${USER_UNIT_DIR}/zocket-web.service" \
283
- "${PY_BIN} -m zocket web --host 127.0.0.1 --port ${WEB_PORT}" \
284
- "${ZOCKET_HOME_DIR}"
285
- write_systemd_user_unit "${USER_UNIT_DIR}/zocket-mcp-sse.service" \
286
- "${PY_BIN} -m zocket mcp --transport sse --mode ${MCP_MODE} --host 127.0.0.1 --port ${MCP_PORT}" \
287
- "${ZOCKET_HOME_DIR}"
288
- write_systemd_user_unit "${USER_UNIT_DIR}/zocket-mcp-http.service" \
289
- "${PY_BIN} -m zocket mcp --transport streamable-http --mode ${MCP_MODE} --host 127.0.0.1 --port ${MCP_STREAM_PORT}" \
290
- "${ZOCKET_HOME_DIR}"
254
+ write_systemd_user_unit "${USER_UNIT_DIR}/zocket.service" "${EXEC_START}" "${ZOCKET_HOME_DIR}"
291
255
  systemctl --user daemon-reload
292
- systemctl --user enable --now zocket-web.service zocket-mcp-sse.service zocket-mcp-http.service >/dev/null
256
+ systemctl --user enable --now zocket.service >/dev/null
293
257
  fi
294
258
 
295
259
  if [[ "$AUTOSTART" == "system" && "$OS" == linux* ]]; then
296
- write_systemd_unit "/etc/systemd/system/zocket-web.service" \
297
- "${PY_BIN} -m zocket web --host 127.0.0.1 --port ${WEB_PORT}" \
298
- "${SERVICE_USER}" "${SERVICE_USER}" "${ZOCKET_HOME_DIR}" "/tmp"
299
- write_systemd_unit "/etc/systemd/system/zocket-mcp-sse.service" \
300
- "${PY_BIN} -m zocket mcp --transport sse --mode ${MCP_MODE} --host 127.0.0.1 --port ${MCP_PORT}" \
301
- "${SERVICE_USER}" "${SERVICE_USER}" "${ZOCKET_HOME_DIR}"
302
- write_systemd_unit "/etc/systemd/system/zocket-mcp-http.service" \
303
- "${PY_BIN} -m zocket mcp --transport streamable-http --mode ${MCP_MODE} --host 127.0.0.1 --port ${MCP_STREAM_PORT}" \
304
- "${SERVICE_USER}" "${SERVICE_USER}" "${ZOCKET_HOME_DIR}"
260
+ write_systemd_unit "/etc/systemd/system/zocket.service" "${EXEC_START}" "${SERVICE_USER}" "${SERVICE_USER}" "${ZOCKET_HOME_DIR}"
305
261
  run_sudo systemctl daemon-reload
306
- run_sudo systemctl enable --now zocket-web.service zocket-mcp-sse.service zocket-mcp-http.service >/dev/null
262
+ run_sudo systemctl enable --now zocket.service >/dev/null
307
263
  fi
308
264
 
309
265
  if [[ "$AUTOSTART" != "none" && "$OS" == darwin* ]]; then
310
266
  PLIST_DIR="$HOME/Library/LaunchAgents"
311
- install_launchd "dev.zocket.web" \
312
- "${PY_BIN} -m zocket web --host 127.0.0.1 --port ${WEB_PORT}" \
313
- "${ZOCKET_HOME_DIR}" "${PLIST_DIR}"
314
- install_launchd "dev.zocket.mcp-sse" \
315
- "${PY_BIN} -m zocket mcp --transport sse --mode ${MCP_MODE} --host 127.0.0.1 --port ${MCP_PORT}" \
316
- "${ZOCKET_HOME_DIR}" "${PLIST_DIR}"
317
- install_launchd "dev.zocket.mcp-streamable" \
318
- "${PY_BIN} -m zocket mcp --transport streamable-http --mode ${MCP_MODE} --host 127.0.0.1 --port ${MCP_STREAM_PORT}" \
319
- "${ZOCKET_HOME_DIR}" "${PLIST_DIR}"
320
- launchctl unload "${PLIST_DIR}/dev.zocket.web.plist" >/dev/null 2>&1 || true
321
- launchctl unload "${PLIST_DIR}/dev.zocket.mcp-sse.plist" >/dev/null 2>&1 || true
322
- launchctl unload "${PLIST_DIR}/dev.zocket.mcp-streamable.plist" >/dev/null 2>&1 || true
323
- launchctl load "${PLIST_DIR}/dev.zocket.web.plist"
324
- launchctl load "${PLIST_DIR}/dev.zocket.mcp-sse.plist"
325
- launchctl load "${PLIST_DIR}/dev.zocket.mcp-streamable.plist"
267
+ install_launchd "dev.zocket" "${EXEC_START}" "${ZOCKET_HOME_DIR}" "${PLIST_DIR}"
268
+ launchctl unload "${PLIST_DIR}/dev.zocket.plist" >/dev/null 2>&1 || true
269
+ launchctl load "${PLIST_DIR}/dev.zocket.plist"
326
270
  fi
327
271
 
328
272
  cat <<EOF
329
273
  zocket installed successfully.
330
274
 
331
- Runtime:
332
- venv: ${VENV_DIR}
333
- zocket: ${ZOCKET_BIN}
334
- ZOCKET_HOME=${ZOCKET_HOME_DIR}
275
+ zocket: ${ZOCKET_BIN}
276
+ ZOCKET_HOME=${ZOCKET_HOME_DIR}
335
277
 
336
278
  Default ports:
337
- web panel: http://127.0.0.1:${WEB_PORT}
279
+ web panel: http://127.0.0.1:${WEB_PORT}$( [[ "$WEB_ENABLED" == "false" ]] && printf ' (disabled)' )
338
280
  MCP SSE: http://127.0.0.1:${MCP_PORT}/sse
339
281
  MCP HTTP: http://127.0.0.1:${MCP_STREAM_PORT}/mcp
340
282
 
341
283
  Next steps:
342
- 1) Open web: ${ZOCKET_BIN} web --host 127.0.0.1 --port ${WEB_PORT}
343
- 2) MCP SSE (Claude Code): ${ZOCKET_BIN} mcp --transport sse --mode ${MCP_MODE} --host 127.0.0.1 --port ${MCP_PORT}
344
- 3) MCP Streamable (Codex): ${ZOCKET_BIN} mcp --transport streamable-http --mode ${MCP_MODE} --host 127.0.0.1 --port ${MCP_STREAM_PORT}
345
- 4) MCP stdio: ${ZOCKET_BIN} mcp --transport stdio --mode ${MCP_MODE}
284
+ 1) Start now: ${EXEC_START}
346
285
  EOF