unified-tvdevelopment-cli 1.0.1-beta.0 → 1.0.2

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 (6) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +255 -1
  3. package/dist/cli.mjs +41211 -750
  4. package/install.ps1 +247 -42
  5. package/install.sh +189 -68
  6. package/package.json +3 -3
package/install.sh CHANGED
@@ -1,17 +1,29 @@
1
1
  #!/usr/bin/env bash
2
- # unified-tvdevelopment-cli — one-line installer
3
- # Supports: LG webOS, Samsung Tizen, Amazon Fire TV, Android TV
2
+ # tvdev-cli — one-line installer (macOS / Linux)
4
3
  #
5
- # curl -fsSL https://raw.githubusercontent.com/FernandoHaeser/unified-tvdevelopment-cli/main/install.sh | bash
4
+ # curl -fsSL https://raw.githubusercontent.com/tvdev-cli/tvdev-cli/main/install.sh | bash
5
+ # curl -fsSL https://raw.githubusercontent.com/tvdev-cli/tvdev-cli/main/install.sh | bash -s -- --beta
6
6
  #
7
7
  set -euo pipefail
8
8
 
9
- PACKAGE="unified-tvdevelopment-cli"
9
+ REPO="tvdev-cli/tvdev-cli"
10
10
  BIN="tvdev"
11
11
  REQUIRED_NODE=18
12
12
  NVM_VERSION="v0.39.7"
13
13
  INSTALL_NODE_VERSION="20"
14
+ INSTALL_DIR="${HOME}/.local/bin"
15
+ VERSION_FILE="${INSTALL_DIR}/.tvdev-version"
16
+ CHANNEL="stable"
14
17
 
18
+ # ── Flags ─────────────────────────────────────────────────────────────────────
19
+ for arg in "${@:-}"; do
20
+ case "$arg" in
21
+ --beta) CHANNEL="beta" ;;
22
+ --stable) CHANNEL="stable" ;;
23
+ esac
24
+ done
25
+
26
+ # ── Colors ────────────────────────────────────────────────────────────────────
15
27
  if [ -t 1 ]; then
16
28
  INDIGO='\033[38;5;99m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
17
29
  RED='\033[0;31m'; BOLD='\033[1m'; DIM='\033[2m'; RESET='\033[0m'
@@ -19,12 +31,14 @@ else
19
31
  INDIGO=''; GREEN=''; YELLOW=''; RED=''; BOLD=''; DIM=''; RESET=''
20
32
  fi
21
33
 
34
+ # ── Helpers ───────────────────────────────────────────────────────────────────
22
35
  banner() {
23
36
  echo ""
24
37
  echo -e "${BOLD}${INDIGO} ◉ TV Dev Manager${RESET}"
25
38
  echo -e " ${INDIGO}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
26
39
  echo -e " ${DIM}Universal Smart TV Development CLI${RESET}"
27
40
  echo -e " ${DIM}LG webOS · Samsung Tizen · Amazon Fire TV · Android TV${RESET}"
41
+ [ "$CHANNEL" = "beta" ] && echo -e " ${YELLOW} channel: beta${RESET}"
28
42
  echo ""
29
43
  }
30
44
 
@@ -32,69 +46,77 @@ step() { echo -e "\n${BOLD}${INDIGO} ▶ $*${RESET}"; }
32
46
  ok() { echo -e " ${GREEN}✓${RESET} $*"; }
33
47
  info() { echo -e " ${INDIGO}●${RESET} $*"; }
34
48
  warn() { echo -e " ${YELLOW}⚠${RESET} $*"; }
35
- skip() { echo -e " ${DIM}– $* (skipped)${RESET}"; }
36
49
  fail() { echo -e "\n ${RED}✗ $*${RESET}\n"; exit 1; }
37
50
 
51
+ semver_gte() {
52
+ local a b
53
+ a=$(echo "$1" | sed 's/-.*//')
54
+ b=$(echo "$2" | sed 's/-.*//')
55
+ [ "$(printf '%s\n%s\n' "$a" "$b" | sort -V | head -1)" = "$b" ]
56
+ }
57
+
38
58
  detect_shell_rc() {
39
59
  case "${SHELL:-}" in
40
- */zsh) echo "$HOME/.zshrc" ;;
41
- */bash)
42
- [ -f "$HOME/.bash_profile" ] && echo "$HOME/.bash_profile" || echo "$HOME/.bashrc"
43
- ;;
60
+ */zsh) echo "$HOME/.zshrc" ;;
61
+ */bash) [ -f "$HOME/.bash_profile" ] && echo "$HOME/.bash_profile" || echo "$HOME/.bashrc" ;;
44
62
  */fish) echo "$HOME/.config/fish/config.fish" ;;
45
63
  *) echo "$HOME/.profile" ;;
46
64
  esac
47
65
  }
48
66
 
49
- idempotent_path_export() {
50
- local bin_dir rc_file export_line
51
- bin_dir=$(npm prefix -g 2>/dev/null)/bin
52
- rc_file=$(detect_shell_rc)
53
-
54
- if echo ":${PATH}:" | grep -q ":${bin_dir}:"; then
55
- ok "PATH already contains npm global bin"
56
- return
57
- fi
67
+ gh_api() {
68
+ curl -fsSL \
69
+ -H "Accept: application/vnd.github+json" \
70
+ -H "X-GitHub-Api-Version: 2022-11-28" \
71
+ "$1"
72
+ }
58
73
 
59
- if [[ "${SHELL:-}" == */fish ]]; then
60
- export_line="set -gx PATH \$PATH ${bin_dir}"
74
+ # ── Resolve latest release tag from GitHub ────────────────────────────────────
75
+ resolve_release_tag() {
76
+ if [ "$CHANNEL" = "beta" ]; then
77
+ gh_api "https://api.github.com/repos/${REPO}/releases" \
78
+ | grep -E '"tag_name"|"prerelease"' \
79
+ | paste - - \
80
+ | awk -F'"' '$0 ~ /"prerelease": true/ { print $4; exit }'
61
81
  else
62
- export_line="export PATH=\"\$PATH:${bin_dir}\""
63
- fi
64
-
65
- if [ -f "$rc_file" ] && grep -qF "$bin_dir" "$rc_file" 2>/dev/null; then
66
- ok "PATH entry already in ${rc_file}"
67
- return
82
+ gh_api "https://api.github.com/repos/${REPO}/releases/latest" \
83
+ | grep '"tag_name"' \
84
+ | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/'
68
85
  fi
69
-
70
- echo "" >> "$rc_file"
71
- echo "# added by unified-tvdevelopment-cli installer" >> "$rc_file"
72
- echo "$export_line" >> "$rc_file"
73
- ok "Added PATH entry to ${rc_file}"
74
- export PATH="${PATH}:${bin_dir}"
75
86
  }
76
87
 
77
- # ── Idempotency ───────────────────────────────────────────────────────────────
78
88
  banner
79
89
 
90
+ # ── Resolve release ───────────────────────────────────────────────────────────
91
+ step "Resolving latest ${CHANNEL} release from GitHub"
92
+
93
+ RELEASE_TAG=$(resolve_release_tag)
94
+ [ -z "$RELEASE_TAG" ] && fail "Could not resolve release from GitHub. Visit https://github.com/${REPO}/releases"
95
+
96
+ RELEASE_VERSION="${RELEASE_TAG#v}"
97
+ info "Latest release : ${RELEASE_TAG}"
98
+
99
+ # ── Idempotency ───────────────────────────────────────────────────────────────
80
100
  step "Checking existing installation"
81
101
 
82
- if command -v "$BIN" &>/dev/null; then
83
- INSTALLED_VER=$(npm list -g --depth=0 "$PACKAGE" 2>/dev/null \
84
- | grep "$PACKAGE" | sed 's/.*@//' | tr -d '[:space:]' || true)
85
- LATEST_VER=$(npm show "$PACKAGE" version 2>/dev/null || true)
102
+ INSTALLED_VER=""
103
+ if [ -f "$VERSION_FILE" ]; then
104
+ INSTALLED_VER=$(cat "$VERSION_FILE" 2>/dev/null | tr -d '[:space:]v' || true)
105
+ fi
86
106
 
107
+ if [ -n "$INSTALLED_VER" ] && command -v "$BIN" &>/dev/null; then
87
108
  ok "${BIN} already installed"
88
- [ -n "$INSTALLED_VER" ] && info "Installed : ${INSTALLED_VER}"
89
- [ -n "$LATEST_VER" ] && info "Latest : ${LATEST_VER}"
109
+ info "Installed : v${INSTALLED_VER}"
110
+ info "Latest : v${RELEASE_VERSION} (${CHANNEL})"
90
111
 
91
- if [ -n "$INSTALLED_VER" ] && [ "$INSTALLED_VER" = "$LATEST_VER" ]; then
112
+ if semver_gte "$INSTALLED_VER" "$RELEASE_VERSION"; then
92
113
  ok "Already up to date — nothing to do"
93
114
  echo ""
94
115
  echo -e " ${BOLD}Run: ${INDIGO}${BIN}${RESET}"
95
116
  echo ""
96
117
  exit 0
97
118
  fi
119
+ info "Update available — reinstalling"
98
120
  else
99
121
  info "${BIN} not yet installed — starting fresh install"
100
122
  fi
@@ -107,7 +129,7 @@ install_node_via_nvm() {
107
129
  export NVM_DIR="${HOME}/.nvm"
108
130
  curl -fsSL "https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh" | bash
109
131
  [ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"
110
- nvm install "$INSTALL_NODE_VERSION" --lts
132
+ nvm install "$INSTALL_NODE_VERSION"
111
133
  nvm use "$INSTALL_NODE_VERSION"
112
134
  nvm alias default "$INSTALL_NODE_VERSION"
113
135
  ok "Node.js $(node --version) installed via nvm"
@@ -117,7 +139,7 @@ if ! command -v node &>/dev/null; then
117
139
  NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
118
140
  if [ -s "$NVM_DIR/nvm.sh" ]; then
119
141
  source "$NVM_DIR/nvm.sh"
120
- if ! command -v node &>/dev/null; then nvm install "$INSTALL_NODE_VERSION" --lts && nvm use "$INSTALL_NODE_VERSION"; fi
142
+ ! command -v node &>/dev/null && nvm install "$INSTALL_NODE_VERSION" && nvm use "$INSTALL_NODE_VERSION"
121
143
  else
122
144
  install_node_via_nvm
123
145
  fi
@@ -126,69 +148,168 @@ fi
126
148
  ! command -v node &>/dev/null && fail "Node.js install failed. Install manually: https://nodejs.org"
127
149
 
128
150
  NODE_MAJOR=$(node --version | sed 's/v//' | cut -d. -f1)
129
- [ "$NODE_MAJOR" -lt "$REQUIRED_NODE" ] && fail "Node.js ${REQUIRED_NODE}+ required. Current: $(node --version)"
151
+ [ "$NODE_MAJOR" -lt "$REQUIRED_NODE" ] && \
152
+ fail "Node.js ${REQUIRED_NODE}+ required (got $(node --version)). Upgrade: https://nodejs.org"
130
153
 
131
154
  ok "Node.js $(node --version)"
132
155
 
133
- # ── npm ───────────────────────────────────────────────────────────────────────
134
- step "Checking npm"
135
- ! command -v npm &>/dev/null && fail "npm not found."
136
- ok "npm $(npm --version)"
156
+ # ── Download binary from GitHub release ───────────────────────────────────────
157
+ step "Downloading ${BIN} ${RELEASE_TAG}"
137
158
 
138
- # ── Install ───────────────────────────────────────────────────────────────────
139
- step "Installing ${PACKAGE}"
140
- info "Running: npm install -g ${PACKAGE}"
141
- echo ""
142
- npm install -g "$PACKAGE"
143
- echo ""
144
- ok "${PACKAGE} installed"
159
+ mkdir -p "$INSTALL_DIR"
160
+ BIN_PATH="${INSTALL_DIR}/${BIN}"
161
+ DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${RELEASE_TAG}/cli.mjs"
162
+
163
+ info "Source : ${DOWNLOAD_URL}"
164
+
165
+ if curl -fsSL --output "$BIN_PATH" "$DOWNLOAD_URL"; then
166
+ chmod +x "$BIN_PATH"
167
+ echo "$RELEASE_VERSION" > "$VERSION_FILE"
168
+ ok "Installed to ${BIN_PATH}"
169
+ else
170
+ warn "GitHub download failed — falling back to npm"
171
+ command -v npm &>/dev/null || fail "npm not found and GitHub download failed. Install Node.js from https://nodejs.org"
172
+ NPM_TAG="latest"
173
+ [ "$CHANNEL" = "beta" ] && NPM_TAG="beta"
174
+ npm install -g "unified-tvdevelopment-cli@${NPM_TAG}" 2>&1 | grep -v "^npm warn" | grep -v "^$" || true
175
+ # point BIN_PATH to npm global bin for the version file
176
+ BIN_PATH=$(npm prefix -g)/bin/${BIN}
177
+ echo "$RELEASE_VERSION" > "$VERSION_FILE"
178
+ fi
145
179
 
146
180
  # ── PATH ──────────────────────────────────────────────────────────────────────
147
181
  step "Setting up PATH"
148
- idempotent_path_export
182
+
183
+ rc_file=$(detect_shell_rc)
184
+
185
+ if echo ":${PATH}:" | grep -q ":${INSTALL_DIR}:"; then
186
+ ok "PATH already contains ${INSTALL_DIR}"
187
+ else
188
+ if [[ "${SHELL:-}" == */fish ]]; then
189
+ grep -qF "$INSTALL_DIR" "$rc_file" 2>/dev/null || \
190
+ echo "set -gx PATH \$PATH ${INSTALL_DIR}" >> "$rc_file"
191
+ else
192
+ if ! grep -qF "$INSTALL_DIR" "$rc_file" 2>/dev/null; then
193
+ echo "" >> "$rc_file"
194
+ echo "# added by tvdev-cli installer" >> "$rc_file"
195
+ echo "export PATH=\"\$PATH:${INSTALL_DIR}\"" >> "$rc_file"
196
+ fi
197
+ fi
198
+ ok "Added ${INSTALL_DIR} to PATH in ${rc_file}"
199
+ export PATH="${PATH}:${INSTALL_DIR}"
200
+ fi
201
+
149
202
  hash -r 2>/dev/null || true
150
203
 
151
204
  if command -v "$BIN" &>/dev/null; then
152
205
  ok "${BIN} is in PATH → $(command -v ${BIN})"
153
206
  else
154
- warn "${BIN} not in PATH for this session. Restart your terminal or:"
155
- echo -e "\n ${BOLD}source $(detect_shell_rc)${RESET}\n"
207
+ warn "${BIN} not in PATH yet restart terminal or run:"
208
+ echo -e "\n source $(detect_shell_rc)\n"
156
209
  fi
157
210
 
158
211
  # ── Platform tools ────────────────────────────────────────────────────────────
159
- step "Checking platform-specific tools"
212
+ step "Checking and installing platform-specific tools"
213
+
214
+ install_ares_cli() {
215
+ info "Installing ares-cli via npm..."
216
+ if npm install -g @webosose/ares-cli 2>&1 | grep -v "^npm warn" | grep -v "^$"; then
217
+ ok "ares-cli (LG webOS) installed → $(command -v ares-setup-device 2>/dev/null || echo 'reload shell')"
218
+ else
219
+ warn "ares-cli install failed — run manually: npm install -g @webosose/ares-cli"
220
+ fi
221
+ }
160
222
 
223
+ install_adb() {
224
+ if [[ "$(uname)" == "Darwin" ]]; then
225
+ if command -v brew &>/dev/null; then
226
+ info "Installing adb via Homebrew..."
227
+ if brew install --quiet android-platform-tools; then
228
+ ok "adb (Fire TV/Android TV) installed → $(command -v adb)"
229
+ else
230
+ warn "Homebrew adb install failed — install Android Studio SDK manually"
231
+ fi
232
+ else
233
+ warn "adb not found — install Homebrew first, then: brew install android-platform-tools"
234
+ fi
235
+ else
236
+ # Linux
237
+ if command -v apt-get &>/dev/null; then
238
+ info "Installing adb via apt..."
239
+ if sudo apt-get install -y -qq adb 2>/dev/null; then
240
+ ok "adb (Fire TV/Android TV) installed → $(command -v adb)"
241
+ else
242
+ warn "apt adb install failed — install Android SDK Platform Tools manually"
243
+ fi
244
+ elif command -v dnf &>/dev/null; then
245
+ info "Installing adb via dnf..."
246
+ if sudo dnf install -y -q android-tools 2>/dev/null; then
247
+ ok "adb (Fire TV/Android TV) installed → $(command -v adb)"
248
+ else
249
+ warn "dnf adb install failed — install Android SDK Platform Tools manually"
250
+ fi
251
+ else
252
+ warn "adb not found — install Android SDK Platform Tools: https://developer.android.com/studio/releases/platform-tools"
253
+ fi
254
+ fi
255
+ }
256
+
257
+ install_inputd_cli() {
258
+ info "Installing inputd-cli via npm..."
259
+ if npm install -g inputd-cli 2>&1 | grep -v "^npm warn" | grep -v "^$"; then
260
+ ok "inputd-cli (Fire TV input) installed"
261
+ else
262
+ warn "inputd-cli install failed — optional tool, skip if not needed"
263
+ fi
264
+ }
265
+
266
+ # ares-cli (LG webOS) — auto-install via npm
161
267
  if command -v ares-setup-device &>/dev/null; then
162
- ok "ares-cli (LG webOS) → $(command -v ares-setup-device)"
268
+ ok "ares-cli (LG webOS) → $(command -v ares-setup-device)"
163
269
  else
164
- warn "ares-cli not found. Install for webOS: npm install -g @webosose/ares-cli"
270
+ warn "ares-cli (LG webOS) not found installing..."
271
+ install_ares_cli
165
272
  fi
166
273
 
274
+ # sdb (Samsung Tizen) — requires Tizen Studio GUI installer, warn only
167
275
  if command -v sdb &>/dev/null; then
168
- ok "sdb (Samsung Tizen) → $(command -v sdb)"
276
+ ok "sdb (Samsung Tizen) → $(command -v sdb)"
169
277
  else
170
- warn "sdb not found. Install Tizen Studio from developer.samsung.com/smarttv"
278
+ warn "sdb (Samsung Tizen) not found requires Tizen Studio: https://developer.samsung.com/smarttv"
171
279
  fi
172
280
 
281
+ # adb (Fire TV / Android TV) — auto-install
173
282
  if command -v adb &>/dev/null; then
174
- ok "adb (Amazon Fire TV / Android TV) → $(command -v adb)"
283
+ ok "adb (Fire TV/Android TV) → $(command -v adb)"
175
284
  else
176
- warn "adb not found. Install: brew install android-platform-tools (macOS) or Android Studio SDK"
285
+ warn "adb (Fire TV/Android TV) not found installing..."
286
+ install_adb
177
287
  fi
178
288
 
289
+ # inputd-cli (optional Fire TV input simulation) — auto-install via npm
179
290
  if command -v inputd-cli &>/dev/null; then
180
- ok "inputd-cli (Amazon Fire TV input) → $(command -v inputd-cli)"
291
+ ok "inputd-cli (Fire TV input) → $(command -v inputd-cli)"
181
292
  else
182
- warn "inputd-cli not found (optional Amazon Fire TV remote input simulation)"
293
+ warn "inputd-cli (Fire TV input) not found installing..."
294
+ install_inputd_cli
183
295
  fi
184
296
 
185
297
  # ── Done ──────────────────────────────────────────────────────────────────────
186
298
  echo ""
187
299
  echo -e "${BOLD}${INDIGO} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
188
- echo -e "${BOLD}${GREEN} ✓ Installation complete!${RESET}"
300
+ echo -e "${BOLD}${GREEN} ✓ Installation complete! (${RELEASE_TAG})${RESET}"
189
301
  echo ""
190
302
  echo -e " Launch TV Dev Manager: ${BOLD}${INDIGO}${BIN}${RESET}"
191
303
  echo ""
192
- echo -e " ${DIM}GitHub : https://github.com/FernandoHaeser/unified-tvdevelopment-cli${RESET}"
304
+ echo -e " ${DIM}GitHub : https://github.com/tvdev-cli/tvdev-cli${RESET}"
193
305
  echo -e " ${DIM}npm : https://npmjs.com/package/unified-tvdevelopment-cli${RESET}"
194
306
  echo ""
307
+ rc_tip=$(detect_shell_rc)
308
+ if ! echo ":${PATH}:" | grep -q ":${INSTALL_DIR}:"; then
309
+ echo -e " ${YELLOW}Tip:${RESET} to make ${BOLD}${INDIGO}${BIN}${RESET} available in every new terminal, add this to ${rc_tip}:"
310
+ echo ""
311
+ echo -e " ${DIM}export PATH=\"\$PATH:${INSTALL_DIR}\"${RESET}"
312
+ echo ""
313
+ echo -e " Then reload: ${DIM}source ${rc_tip}${RESET}"
314
+ echo ""
315
+ fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unified-tvdevelopment-cli",
3
- "version": "1.0.1-beta.0",
3
+ "version": "1.0.2",
4
4
  "description": "Universal TUI manager for Smart TV development — LG webOS, Samsung Tizen, Amazon Fire TV, Android TV",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,7 +10,7 @@
10
10
  "node": ">=18.0.0"
11
11
  },
12
12
  "scripts": {
13
- "build": "mkdir -p dist && esbuild src/index.js --bundle --packages=external --platform=node --format=esm --outfile=dist/_bundle.mjs --loader:.js=jsx && printf '#!/usr/bin/env node\\n' | cat - dist/_bundle.mjs > dist/cli.mjs && chmod +x dist/cli.mjs && rm dist/_bundle.mjs",
13
+ "build": "mkdir -p dist && esbuild src/index.js --bundle --alias:react-devtools-core=./scripts/devtools-stub.js --platform=node --format=esm --banner:js=\"import{createRequire}from'module';const require=createRequire(import.meta.url);\" --outfile=dist/_bundle.mjs --loader:.js=jsx && printf '#!/usr/bin/env node\\n' | cat - dist/_bundle.mjs > dist/cli.mjs && chmod +x dist/cli.mjs && rm dist/_bundle.mjs",
14
14
  "start": "npm run build && node dist/cli.mjs",
15
15
  "dev": "npm run build && node dist/cli.mjs",
16
16
  "prepare": "npm run build",
@@ -39,7 +39,7 @@
39
39
  "license": "MIT",
40
40
  "repository": {
41
41
  "type": "git",
42
- "url": "https://github.com/FernandoHaeser/unified-tvdevelopment-cli"
42
+ "url": "git+https://github.com/tvdev-cli/tvdev-cli.git"
43
43
  },
44
44
  "files": [
45
45
  "dist/",