@ao_zorin/zocket 1.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.
@@ -0,0 +1,95 @@
1
+ # Local Models (Ollama / Hugging Face) with zocket Workflows
2
+
3
+ zocket itself is model-agnostic.
4
+ You can use local models in agent clients while zocket provides secrets/MCP.
5
+
6
+ ## 1) Ollama (local)
7
+
8
+ Start Ollama and pull a model:
9
+ ```bash
10
+ ollama serve
11
+ ollama pull qwen2.5-coder:7b
12
+ ```
13
+
14
+ Ollama OpenAI-compatible endpoint is typically:
15
+ ```text
16
+ http://127.0.0.1:11434/v1
17
+ ```
18
+
19
+ ### OpenCode + Ollama
20
+
21
+ `~/.config/opencode/opencode.json`:
22
+ ```json
23
+ {
24
+ "$schema": "https://opencode.ai/config.json",
25
+ "provider": {
26
+ "ollama": {
27
+ "npm": "opencode-ollama",
28
+ "name": "Ollama",
29
+ "models": {
30
+ "qwen2.5-coder:7b": {}
31
+ }
32
+ }
33
+ },
34
+ "agent": {
35
+ "coder": {
36
+ "model": "ollama/qwen2.5-coder:7b"
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ ### Qwen CLI + Ollama (OpenAI-compatible)
43
+
44
+ `~/.qwen/settings.json`:
45
+ ```json
46
+ {
47
+ "modelProviders": {
48
+ "local_ollama": {
49
+ "name": "Local Ollama",
50
+ "baseURL": "http://127.0.0.1:11434/v1",
51
+ "apiKey": "ollama",
52
+ "models": ["qwen2.5-coder:7b"]
53
+ }
54
+ },
55
+ "model": "local_ollama/qwen2.5-coder:7b"
56
+ }
57
+ ```
58
+
59
+ ## 2) Hugging Face local models
60
+
61
+ Recommended path:
62
+ - run local Text Generation Inference (TGI) server
63
+ - expose OpenAI-compatible endpoint
64
+ - connect client via custom provider settings
65
+
66
+ Typical local endpoint:
67
+ ```text
68
+ http://127.0.0.1:8080/v1
69
+ ```
70
+
71
+ Example (Qwen CLI custom provider):
72
+ ```json
73
+ {
74
+ "modelProviders": {
75
+ "local_hf_tgi": {
76
+ "name": "HF TGI Local",
77
+ "baseURL": "http://127.0.0.1:8080/v1",
78
+ "apiKey": "hf-local",
79
+ "models": ["Qwen/Qwen2.5-Coder-7B-Instruct"]
80
+ }
81
+ },
82
+ "model": "local_hf_tgi/Qwen/Qwen2.5-Coder-7B-Instruct"
83
+ }
84
+ ```
85
+
86
+ ## 3) Clients that are primarily cloud-first
87
+
88
+ - Codex CLI / Claude / Antigravity are primarily documented for hosted model backends.
89
+ - Keep zocket MCP integration enabled independently from model backend choice.
90
+
91
+ ## 4) Security notes
92
+
93
+ - Keep local model APIs on loopback only (`127.0.0.1`).
94
+ - Do not expose local model endpoints publicly without auth and TLS.
95
+ - Keep zocket in `metadata` mode by default for MCP clients.
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@ao_zorin/zocket",
3
+ "version": "1.0.0",
4
+ "description": "Cross-platform npm launcher for Zocket (local MCP + web vault)",
5
+ "license": "MIT",
6
+ "private": false,
7
+ "type": "commonjs",
8
+ "bin": {
9
+ "zocket": "bin/zocket.cjs",
10
+ "zocket-setup": "bin/zocket-setup.cjs"
11
+ },
12
+ "files": [
13
+ "bin/",
14
+ "docs/AI_AUTODEPLOY.md",
15
+ "docs/CLIENTS_MCP.md",
16
+ "docs/INSTALL.md",
17
+ "docs/LOCAL_MODELS.md",
18
+ "scripts/ai-autodeploy.py",
19
+ "scripts/install-zocket.sh",
20
+ "scripts/install-zocket.ps1",
21
+ "zocket/*.py",
22
+ "zocket/templates/*.html",
23
+ "pyproject.toml",
24
+ "README.md",
25
+ "LICENSE"
26
+ ],
27
+ "engines": {
28
+ "node": ">=18"
29
+ },
30
+ "scripts": {
31
+ "test:python": "PYTHONPATH=. pytest -q",
32
+ "smoke:npm": "node ./bin/zocket.cjs --help"
33
+ },
34
+ "keywords": [
35
+ "mcp",
36
+ "model-context-protocol",
37
+ "secrets",
38
+ "vault",
39
+ "cli",
40
+ "agents",
41
+ "codex",
42
+ "claude"
43
+ ],
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "https://github.com/aozorin/zocket.git"
47
+ },
48
+ "homepage": "https://github.com/aozorin/zocket#readme",
49
+ "bugs": {
50
+ "url": "https://github.com/aozorin/zocket/issues"
51
+ }
52
+ }
package/pyproject.toml ADDED
@@ -0,0 +1,29 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "zocket"
7
+ version = "1.0.0"
8
+ description = "Local MCP + web vault for project auth secrets"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ dependencies = [
12
+ "cryptography>=43.0.0",
13
+ "flask>=3.0.0",
14
+ "keyring>=25.0.0",
15
+ "mcp>=1.0.0",
16
+ "waitress>=3.0.0",
17
+ ]
18
+
19
+ [project.scripts]
20
+ zocket = "zocket.cli:main"
21
+
22
+ [project.optional-dependencies]
23
+ dev = ["pytest>=8.0.0"]
24
+
25
+ [tool.setuptools.packages.find]
26
+ include = ["zocket*"]
27
+
28
+ [tool.setuptools.package-data]
29
+ zocket = ["templates/*.html"]
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import os
6
+ import platform
7
+ import shutil
8
+ import subprocess
9
+ import sys
10
+ from pathlib import Path
11
+
12
+
13
+ def run(cmd: list[str]) -> None:
14
+ print(f"[ai-autodeploy] $ {' '.join(cmd)}")
15
+ cp = subprocess.run(cmd, check=False)
16
+ if cp.returncode != 0:
17
+ raise RuntimeError(f"Command failed with code {cp.returncode}: {' '.join(cmd)}")
18
+
19
+
20
+ def ensure_tool(name: str) -> str:
21
+ path = shutil.which(name)
22
+ if not path:
23
+ raise RuntimeError(f"Required tool not found: {name}")
24
+ return path
25
+
26
+
27
+ def clone_or_update(repo_url: str, repo_ref: str, checkout_dir: Path) -> None:
28
+ git = ensure_tool("git")
29
+ if (checkout_dir / ".git").exists():
30
+ run([git, "-C", str(checkout_dir), "fetch", "--all", "--tags"])
31
+ run([git, "-C", str(checkout_dir), "checkout", repo_ref])
32
+ run([git, "-C", str(checkout_dir), "pull", "--ff-only"])
33
+ return
34
+ checkout_dir.parent.mkdir(parents=True, exist_ok=True)
35
+ run([git, "clone", "--depth", "1", "--branch", repo_ref, repo_url, str(checkout_dir)])
36
+
37
+
38
+ def default_checkout_dir() -> Path:
39
+ if sys.platform.startswith("win"):
40
+ root = Path(os.environ.get("LOCALAPPDATA", str(Path.home() / "AppData" / "Local")))
41
+ return root / "zocket" / "bootstrap-src"
42
+ return Path.home() / ".local" / "share" / "zocket" / "bootstrap-src"
43
+
44
+
45
+ def main() -> int:
46
+ ap = argparse.ArgumentParser(description="One-file zocket bootstrap for AI agents.")
47
+ ap.add_argument("--repo-url", default="https://github.com/your-org/zocket.git")
48
+ ap.add_argument("--repo-ref", default="main")
49
+ ap.add_argument("--checkout-dir", default=str(default_checkout_dir()))
50
+ ap.add_argument("--lang", default="en", choices=["en", "ru"])
51
+ ap.add_argument("--web-port", default="18001")
52
+ ap.add_argument("--mcp-port", default="18002")
53
+ ap.add_argument("--mcp-mode", default="metadata", choices=["metadata", "admin"])
54
+ ap.add_argument("--autostart", default="user", choices=["user", "system", "none"])
55
+ ap.add_argument("--service-user", default="zocketd")
56
+ ap.add_argument("--zocket-home", default=str(Path.home() / ".zocket"))
57
+ args = ap.parse_args()
58
+
59
+ checkout_dir = Path(args.checkout_dir).expanduser().resolve()
60
+ clone_or_update(args.repo_url, args.repo_ref, checkout_dir)
61
+
62
+ system = platform.system().lower()
63
+ if system == "windows":
64
+ ps = shutil.which("pwsh") or shutil.which("powershell")
65
+ if not ps:
66
+ raise RuntimeError("PowerShell not found")
67
+ installer = checkout_dir / "scripts" / "install-zocket.ps1"
68
+ cmd = [
69
+ ps,
70
+ "-ExecutionPolicy",
71
+ "Bypass",
72
+ "-File",
73
+ str(installer),
74
+ "-Source",
75
+ "Local",
76
+ "-InstallRoot",
77
+ str(Path(os.environ.get("LOCALAPPDATA", str(Path.home() / "AppData" / "Local"))) / "zocket"),
78
+ "-ZocketHome",
79
+ args.zocket_home,
80
+ "-Lang",
81
+ args.lang,
82
+ "-WebPort",
83
+ args.web_port,
84
+ "-McpPort",
85
+ args.mcp_port,
86
+ "-McpMode",
87
+ args.mcp_mode,
88
+ ]
89
+ if args.autostart != "none":
90
+ cmd.append("-EnableAutostart")
91
+ run(cmd)
92
+ else:
93
+ bash = ensure_tool("bash")
94
+ installer = checkout_dir / "scripts" / "install-zocket.sh"
95
+ run(
96
+ [
97
+ bash,
98
+ str(installer),
99
+ "--source",
100
+ "local",
101
+ "--install-root",
102
+ str(checkout_dir.parent),
103
+ "--zocket-home",
104
+ args.zocket_home,
105
+ "--lang",
106
+ args.lang,
107
+ "--web-port",
108
+ args.web_port,
109
+ "--mcp-port",
110
+ args.mcp_port,
111
+ "--mcp-mode",
112
+ args.mcp_mode,
113
+ "--autostart",
114
+ args.autostart,
115
+ "--service-user",
116
+ args.service_user,
117
+ ]
118
+ )
119
+
120
+ print("[ai-autodeploy] Completed successfully.")
121
+ print("[ai-autodeploy] Web: http://127.0.0.1:18001")
122
+ print("[ai-autodeploy] MCP: http://127.0.0.1:18002/mcp")
123
+ return 0
124
+
125
+
126
+ if __name__ == "__main__":
127
+ raise SystemExit(main())
@@ -0,0 +1,116 @@
1
+ Param(
2
+ [ValidateSet("Auto", "Local", "Git", "PyPI")]
3
+ [string]$Source = "Auto",
4
+ [string]$RepoUrl = "https://github.com/your-org/zocket.git",
5
+ [string]$RepoRef = "main",
6
+ [string]$InstallRoot = "$env:LOCALAPPDATA\zocket",
7
+ [string]$ZocketHome = "$env:USERPROFILE\.zocket",
8
+ [ValidateSet("en", "ru")]
9
+ [string]$Lang = "en",
10
+ [int]$WebPort = 18001,
11
+ [int]$McpPort = 18002,
12
+ [int]$McpStreamPort = 18003,
13
+ [ValidateSet("metadata", "admin")]
14
+ [string]$McpMode = "metadata",
15
+ [switch]$EnableAutostart
16
+ )
17
+
18
+ $ErrorActionPreference = "Stop"
19
+
20
+ function Resolve-Python {
21
+ if (Get-Command py -ErrorAction SilentlyContinue) {
22
+ return @{Cmd = "py"; Prefix = @("-3")}
23
+ }
24
+ if (Get-Command python -ErrorAction SilentlyContinue) {
25
+ return @{Cmd = "python"; Prefix = @()}
26
+ }
27
+ throw "Python 3.10+ not found. Install Python and rerun."
28
+ }
29
+
30
+ function Run-Step([string]$Cmd, [string[]]$Args) {
31
+ & $Cmd @Args
32
+ if ($LASTEXITCODE -ne 0) {
33
+ throw "Command failed: $Cmd $($Args -join ' ')"
34
+ }
35
+ }
36
+
37
+ function Ensure-Dir([string]$Path) {
38
+ if (-not (Test-Path -LiteralPath $Path)) {
39
+ New-Item -ItemType Directory -Path $Path | Out-Null
40
+ }
41
+ }
42
+
43
+ $repoRoot = Split-Path -Parent $PSScriptRoot
44
+ if ($Source -eq "Auto") {
45
+ if (Test-Path -LiteralPath (Join-Path $repoRoot "pyproject.toml")) {
46
+ $Source = "Local"
47
+ } else {
48
+ $Source = "Git"
49
+ }
50
+ }
51
+
52
+ Ensure-Dir $InstallRoot
53
+ $srcDir = Join-Path $InstallRoot "src"
54
+
55
+ $pkgSource = $null
56
+ if ($Source -eq "Local") {
57
+ $pkgSource = $repoRoot
58
+ } elseif ($Source -eq "Git") {
59
+ if (Test-Path -LiteralPath (Join-Path $srcDir ".git")) {
60
+ Run-Step "git" @("-C", $srcDir, "fetch", "--all", "--tags")
61
+ Run-Step "git" @("-C", $srcDir, "checkout", $RepoRef)
62
+ Run-Step "git" @("-C", $srcDir, "pull", "--ff-only")
63
+ } else {
64
+ if (Test-Path -LiteralPath $srcDir) {
65
+ Remove-Item -LiteralPath $srcDir -Recurse -Force
66
+ }
67
+ Run-Step "git" @("clone", "--depth", "1", "--branch", $RepoRef, $RepoUrl, $srcDir)
68
+ }
69
+ $pkgSource = $srcDir
70
+ } else {
71
+ $pkgSource = "zocket"
72
+ }
73
+
74
+ $py = Resolve-Python
75
+ $venvDir = Join-Path $InstallRoot "venv"
76
+ $venvPy = Join-Path $venvDir "Scripts\python.exe"
77
+ $zocketExe = Join-Path $venvDir "Scripts\zocket.exe"
78
+
79
+ Run-Step $py.Cmd ($py.Prefix + @("-m", "venv", $venvDir))
80
+ Run-Step $venvPy @("-m", "pip", "install", "--upgrade", "pip", "setuptools", "wheel")
81
+
82
+ if ($Source -eq "PyPI") {
83
+ Run-Step $venvPy @("-m", "pip", "install", "--upgrade", $pkgSource)
84
+ } else {
85
+ Run-Step $venvPy @("-m", "pip", "install", "--upgrade", $pkgSource)
86
+ }
87
+
88
+ Ensure-Dir $ZocketHome
89
+ $env:ZOCKET_HOME = $ZocketHome
90
+
91
+ if (-not (Test-Path -LiteralPath (Join-Path $ZocketHome "vault.enc"))) {
92
+ Run-Step $zocketExe @("init")
93
+ }
94
+ Run-Step $zocketExe @("config", "set-language", $Lang)
95
+
96
+ if ($EnableAutostart) {
97
+ $webTask = "ZocketWeb"
98
+ $mcpSseTask = "ZocketMcpSse"
99
+ $mcpStreamTask = "ZocketMcpStreamable"
100
+
101
+ $webCmd = "`"$venvPy`" -m zocket web --host 127.0.0.1 --port $WebPort"
102
+ $mcpSseCmd = "`"$venvPy`" -m zocket mcp --transport sse --mode $McpMode --host 127.0.0.1 --port $McpPort"
103
+ $mcpStreamCmd = "`"$venvPy`" -m zocket mcp --transport streamable-http --mode $McpMode --host 127.0.0.1 --port $McpStreamPort"
104
+
105
+ schtasks /Create /F /SC ONLOGON /RL LIMITED /TN $webTask /TR $webCmd | Out-Null
106
+ schtasks /Create /F /SC ONLOGON /RL LIMITED /TN $mcpSseTask /TR $mcpSseCmd | Out-Null
107
+ schtasks /Create /F /SC ONLOGON /RL LIMITED /TN $mcpStreamTask /TR $mcpStreamCmd | Out-Null
108
+ }
109
+
110
+ Write-Output "zocket installed successfully."
111
+ Write-Output "venv: $venvDir"
112
+ Write-Output "zocket: $zocketExe"
113
+ Write-Output "ZOCKET_HOME=$ZocketHome"
114
+ Write-Output "web panel: http://127.0.0.1:$WebPort"
115
+ Write-Output "mcp sse: http://127.0.0.1:$McpPort/sse"
116
+ Write-Output "mcp http: http://127.0.0.1:$McpStreamPort/mcp"
@@ -0,0 +1,228 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+ REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
6
+
7
+ SOURCE_MODE="${SOURCE_MODE:-auto}" # auto|local|git|pypi
8
+ REPO_URL="${REPO_URL:-https://github.com/your-org/zocket.git}"
9
+ REPO_REF="${REPO_REF:-main}"
10
+ INSTALL_ROOT="${INSTALL_ROOT:-$HOME/.local/share/zocket}"
11
+ ZOCKET_HOME_DIR="${ZOCKET_HOME_DIR:-$HOME/.zocket}"
12
+ LANGUAGE="${LANGUAGE:-en}" # en|ru
13
+ WEB_PORT="${WEB_PORT:-18001}"
14
+ MCP_PORT="${MCP_PORT:-18002}"
15
+ MCP_STREAM_PORT="${MCP_STREAM_PORT:-18003}"
16
+ MCP_MODE="${MCP_MODE:-metadata}" # metadata|admin
17
+ AUTOSTART="${AUTOSTART:-user}" # user|system|none
18
+ SERVICE_USER="${SERVICE_USER:-zocketd}"
19
+
20
+ usage() {
21
+ cat <<EOF
22
+ Usage: $(basename "$0") [options]
23
+
24
+ Options:
25
+ --source <auto|local|git|pypi>
26
+ --repo-url <git-url>
27
+ --repo-ref <branch-or-tag>
28
+ --install-root <path>
29
+ --zocket-home <path>
30
+ --lang <en|ru>
31
+ --web-port <port>
32
+ --mcp-port <port>
33
+ --mcp-stream-port <port>
34
+ --mcp-mode <metadata|admin>
35
+ --autostart <user|system|none>
36
+ --service-user <name>
37
+ -h, --help
38
+
39
+ Environment variables with same names are also supported.
40
+ EOF
41
+ }
42
+
43
+ while [[ $# -gt 0 ]]; do
44
+ case "$1" in
45
+ --source) SOURCE_MODE="$2"; shift 2 ;;
46
+ --repo-url) REPO_URL="$2"; shift 2 ;;
47
+ --repo-ref) REPO_REF="$2"; shift 2 ;;
48
+ --install-root) INSTALL_ROOT="$2"; shift 2 ;;
49
+ --zocket-home) ZOCKET_HOME_DIR="$2"; shift 2 ;;
50
+ --lang) LANGUAGE="$2"; shift 2 ;;
51
+ --web-port) WEB_PORT="$2"; shift 2 ;;
52
+ --mcp-port) MCP_PORT="$2"; shift 2 ;;
53
+ --mcp-stream-port) MCP_STREAM_PORT="$2"; shift 2 ;;
54
+ --mcp-mode) MCP_MODE="$2"; shift 2 ;;
55
+ --autostart) AUTOSTART="$2"; shift 2 ;;
56
+ --service-user) SERVICE_USER="$2"; shift 2 ;;
57
+ -h|--help) usage; exit 0 ;;
58
+ *) echo "Unknown argument: $1" >&2; usage; exit 2 ;;
59
+ esac
60
+ done
61
+
62
+ have_cmd() {
63
+ command -v "$1" >/dev/null 2>&1
64
+ }
65
+
66
+ run_sudo() {
67
+ if have_cmd sudo; then
68
+ sudo "$@"
69
+ else
70
+ "$@"
71
+ fi
72
+ }
73
+
74
+ install_python_linux() {
75
+ if have_cmd apt-get; then
76
+ run_sudo apt-get update
77
+ run_sudo apt-get install -y python3 python3-venv python3-pip git curl
78
+ return
79
+ fi
80
+ if have_cmd dnf; then
81
+ run_sudo dnf install -y python3 python3-pip python3-virtualenv git curl
82
+ return
83
+ fi
84
+ if have_cmd yum; then
85
+ run_sudo yum install -y python3 python3-pip git curl
86
+ return
87
+ fi
88
+ if have_cmd pacman; then
89
+ run_sudo pacman -Sy --noconfirm python python-pip git curl
90
+ return
91
+ fi
92
+ if have_cmd zypper; then
93
+ run_sudo zypper install -y python3 python3-pip python3-virtualenv git curl
94
+ return
95
+ fi
96
+ if have_cmd apk; then
97
+ run_sudo apk add --no-cache python3 py3-pip py3-virtualenv git curl
98
+ return
99
+ fi
100
+ echo "Unsupported Linux package manager. Install Python 3.10+, pip, and venv manually." >&2
101
+ exit 1
102
+ }
103
+
104
+ install_python_macos() {
105
+ if ! have_cmd brew; then
106
+ echo "Homebrew not found. Install Homebrew first: https://brew.sh" >&2
107
+ exit 1
108
+ fi
109
+ brew install python git curl
110
+ }
111
+
112
+ OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
113
+ if ! have_cmd python3; then
114
+ echo "python3 not found, installing dependencies..."
115
+ case "$OS" in
116
+ linux*) install_python_linux ;;
117
+ darwin*) install_python_macos ;;
118
+ *)
119
+ echo "Unsupported OS for this installer: $OS" >&2
120
+ exit 1
121
+ ;;
122
+ esac
123
+ fi
124
+
125
+ if ! have_cmd git; then
126
+ echo "git not found, installing..."
127
+ case "$OS" in
128
+ linux*) install_python_linux ;;
129
+ darwin*) install_python_macos ;;
130
+ *) echo "Install git manually and rerun." >&2; exit 1 ;;
131
+ esac
132
+ fi
133
+
134
+ if [[ "$SOURCE_MODE" == "auto" ]]; then
135
+ if [[ -f "${REPO_ROOT}/pyproject.toml" ]]; then
136
+ SOURCE_MODE="local"
137
+ else
138
+ SOURCE_MODE="git"
139
+ fi
140
+ fi
141
+
142
+ PKG_SOURCE=""
143
+ SRC_DIR="${INSTALL_ROOT}/src"
144
+
145
+ mkdir -p "${INSTALL_ROOT}"
146
+
147
+ if [[ "$SOURCE_MODE" == "local" ]]; then
148
+ PKG_SOURCE="${REPO_ROOT}"
149
+ elif [[ "$SOURCE_MODE" == "git" ]]; then
150
+ if [[ -d "${SRC_DIR}/.git" ]]; then
151
+ git -C "${SRC_DIR}" fetch --all --tags
152
+ git -C "${SRC_DIR}" checkout "${REPO_REF}"
153
+ git -C "${SRC_DIR}" pull --ff-only
154
+ else
155
+ rm -rf "${SRC_DIR}"
156
+ git clone --depth 1 --branch "${REPO_REF}" "${REPO_URL}" "${SRC_DIR}"
157
+ fi
158
+ PKG_SOURCE="${SRC_DIR}"
159
+ elif [[ "$SOURCE_MODE" == "pypi" ]]; then
160
+ PKG_SOURCE="zocket"
161
+ else
162
+ echo "Invalid source mode: $SOURCE_MODE" >&2
163
+ exit 2
164
+ fi
165
+
166
+ VENV_DIR="${INSTALL_ROOT}/venv"
167
+ PY_BIN="${VENV_DIR}/bin/python3"
168
+ ZOCKET_BIN="${VENV_DIR}/bin/zocket"
169
+
170
+ python3 -m venv "${VENV_DIR}"
171
+ "${PY_BIN}" -m pip install --upgrade pip setuptools wheel
172
+
173
+ if [[ "$SOURCE_MODE" == "pypi" ]]; then
174
+ "${PY_BIN}" -m pip install --upgrade "${PKG_SOURCE}"
175
+ else
176
+ "${PY_BIN}" -m pip install --upgrade "${PKG_SOURCE}"
177
+ fi
178
+
179
+ mkdir -p "$HOME/.local/bin"
180
+ ln -sf "${ZOCKET_BIN}" "$HOME/.local/bin/zocket"
181
+
182
+ export ZOCKET_HOME="${ZOCKET_HOME_DIR}"
183
+ mkdir -p "${ZOCKET_HOME_DIR}"
184
+
185
+ if [[ ! -f "${ZOCKET_HOME_DIR}/vault.enc" ]]; then
186
+ "${ZOCKET_BIN}" init
187
+ fi
188
+
189
+ "${ZOCKET_BIN}" config set-language "${LANGUAGE}" >/dev/null
190
+
191
+ if [[ "$AUTOSTART" == "user" && "$OS" == linux* ]]; then
192
+ "${ZOCKET_BIN}" autostart install \
193
+ --target both \
194
+ --web-port "${WEB_PORT}" \
195
+ --mcp-port "${MCP_PORT}" \
196
+ --mcp-mode "${MCP_MODE}" \
197
+ --zocket-home "${ZOCKET_HOME_DIR}" >/dev/null
198
+ fi
199
+
200
+ if [[ "$AUTOSTART" == "system" && "$OS" == linux* ]]; then
201
+ run_sudo env ZOCKET_HOME="${ZOCKET_HOME_DIR}" "${PY_BIN}" -m zocket harden install-linux-system \
202
+ --service-user "${SERVICE_USER}" \
203
+ --zocket-home "${ZOCKET_HOME_DIR}" \
204
+ --web-port "${WEB_PORT}" \
205
+ --mcp-host 127.0.0.1 \
206
+ --mcp-port "${MCP_PORT}" \
207
+ --mcp-mode "${MCP_MODE}" >/dev/null
208
+ fi
209
+
210
+ cat <<EOF
211
+ zocket installed successfully.
212
+
213
+ Runtime:
214
+ venv: ${VENV_DIR}
215
+ zocket: ${ZOCKET_BIN}
216
+ ZOCKET_HOME=${ZOCKET_HOME_DIR}
217
+
218
+ Default ports:
219
+ web panel: http://127.0.0.1:${WEB_PORT}
220
+ MCP SSE: http://127.0.0.1:${MCP_PORT}/sse
221
+ MCP HTTP: http://127.0.0.1:${MCP_STREAM_PORT}/mcp
222
+
223
+ Next steps:
224
+ 1) Open web: ${ZOCKET_BIN} web --host 127.0.0.1 --port ${WEB_PORT}
225
+ 2) MCP SSE (Claude Code): ${ZOCKET_BIN} mcp --transport sse --mode ${MCP_MODE} --host 127.0.0.1 --port ${MCP_PORT}
226
+ 3) MCP Streamable (Codex): ${ZOCKET_BIN} mcp --transport streamable-http --mode ${MCP_MODE} --host 127.0.0.1 --port ${MCP_STREAM_PORT}
227
+ 4) MCP stdio: ${ZOCKET_BIN} mcp --transport stdio --mode ${MCP_MODE}
228
+ EOF
@@ -0,0 +1,2 @@
1
+ __all__ = ["__version__"]
2
+ __version__ = "1.0.0"
@@ -0,0 +1,5 @@
1
+ from .cli import main
2
+
3
+
4
+ if __name__ == "__main__":
5
+ raise SystemExit(main())