unified-tvdevelopment-cli 1.0.1-beta.0 → 1.0.1
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.
- package/LICENSE +21 -0
- package/README.md +255 -1
- package/dist/cli.mjs +41177 -733
- package/install.ps1 +119 -29
- package/install.sh +115 -64
- package/package.json +3 -3
package/install.ps1
CHANGED
|
@@ -1,81 +1,171 @@
|
|
|
1
1
|
# unified-tvdevelopment-cli — Windows installer
|
|
2
|
-
# Run:
|
|
2
|
+
# Run:
|
|
3
|
+
# iwr -useb https://raw.githubusercontent.com/tvdev-cli/tvdev-cli/main/install.ps1 | iex
|
|
4
|
+
# iwr -useb https://raw.githubusercontent.com/tvdev-cli/tvdev-cli/main/install.ps1 | iex # then pass -Beta
|
|
5
|
+
|
|
6
|
+
param(
|
|
7
|
+
[switch]$Beta,
|
|
8
|
+
[string]$Tag = "latest"
|
|
9
|
+
)
|
|
3
10
|
|
|
4
11
|
$ErrorActionPreference = 'Stop'
|
|
5
12
|
$Package = "unified-tvdevelopment-cli"
|
|
6
13
|
$Bin = "tvdev"
|
|
14
|
+
$RequiredNodeMajor = 18
|
|
15
|
+
|
|
16
|
+
if ($Beta) { $Tag = "beta" }
|
|
7
17
|
|
|
18
|
+
# ── Helpers ───────────────────────────────────────────────────────────────────
|
|
8
19
|
function Write-Banner {
|
|
9
20
|
Write-Host ""
|
|
10
|
-
Write-Host " [TV Dev Manager]" -ForegroundColor Cyan
|
|
21
|
+
Write-Host " [TV Dev Manager]" -ForegroundColor Cyan -NoNewline
|
|
22
|
+
if ($Tag -ne "latest") {
|
|
23
|
+
Write-Host " tag: $Tag" -ForegroundColor Yellow
|
|
24
|
+
} else {
|
|
25
|
+
Write-Host ""
|
|
26
|
+
}
|
|
11
27
|
Write-Host " Universal Smart TV Development CLI" -ForegroundColor DarkGray
|
|
12
28
|
Write-Host " LG webOS · Samsung Tizen · Amazon Fire TV · Android TV" -ForegroundColor DarkGray
|
|
13
29
|
Write-Host ""
|
|
14
30
|
}
|
|
15
31
|
|
|
16
|
-
function Write-Step
|
|
17
|
-
function Write-Ok
|
|
18
|
-
function Write-
|
|
19
|
-
function Write-
|
|
32
|
+
function Write-Step { param($msg) Write-Host "`n > $msg" -ForegroundColor Cyan }
|
|
33
|
+
function Write-Ok { param($msg) Write-Host " [OK] $msg" -ForegroundColor Green }
|
|
34
|
+
function Write-Info { param($msg) Write-Host " [..] $msg" -ForegroundColor Blue }
|
|
35
|
+
function Write-Warn { param($msg) Write-Host " [!!] $msg" -ForegroundColor Yellow }
|
|
36
|
+
function Write-Fail { param($msg) Write-Host "`n [XX] $msg`n" -ForegroundColor Red; exit 1 }
|
|
37
|
+
|
|
38
|
+
function Get-SemverParts {
|
|
39
|
+
param([string]$v)
|
|
40
|
+
$core = ($v -split '-')[0]
|
|
41
|
+
return ($core -split '\.' | ForEach-Object { [int]$_ })
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function Compare-Version {
|
|
45
|
+
param([string]$installed, [string]$latest)
|
|
46
|
+
$a = Get-SemverParts $installed
|
|
47
|
+
$b = Get-SemverParts $latest
|
|
48
|
+
for ($i = 0; $i -lt [Math]::Max($a.Count, $b.Count); $i++) {
|
|
49
|
+
$av = if ($i -lt $a.Count) { $a[$i] } else { 0 }
|
|
50
|
+
$bv = if ($i -lt $b.Count) { $b[$i] } else { 0 }
|
|
51
|
+
if ($av -gt $bv) { return 1 }
|
|
52
|
+
if ($av -lt $bv) { return -1 }
|
|
53
|
+
}
|
|
54
|
+
return 0
|
|
55
|
+
}
|
|
20
56
|
|
|
21
57
|
Write-Banner
|
|
22
58
|
|
|
23
|
-
#
|
|
59
|
+
# ── Idempotency ───────────────────────────────────────────────────────────────
|
|
60
|
+
Write-Step "Checking existing installation"
|
|
61
|
+
|
|
62
|
+
$installedVer = ""
|
|
63
|
+
$latestVer = ""
|
|
64
|
+
|
|
65
|
+
if (Get-Command $Bin -ErrorAction SilentlyContinue) {
|
|
66
|
+
try {
|
|
67
|
+
$installedVer = (npm list -g --depth=0 $Package 2>$null | Select-String $Package) `
|
|
68
|
+
-replace ".*@", "" | ForEach-Object { $_.Trim() }
|
|
69
|
+
$latestVer = (npm show "${Package}@${Tag}" version 2>$null).Trim()
|
|
70
|
+
} catch {}
|
|
71
|
+
|
|
72
|
+
Write-Ok "$Bin already installed"
|
|
73
|
+
if ($installedVer) { Write-Info "Installed : $installedVer" }
|
|
74
|
+
if ($latestVer) { Write-Info "Latest : $latestVer ($Tag)" }
|
|
75
|
+
|
|
76
|
+
if ($installedVer -and $latestVer -and (Compare-Version $installedVer $latestVer) -ge 0) {
|
|
77
|
+
Write-Ok "Already up to date — nothing to do"
|
|
78
|
+
Write-Host "`n Run: $Bin`n" -ForegroundColor Cyan
|
|
79
|
+
exit 0
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
Write-Info "Update available — reinstalling"
|
|
83
|
+
} else {
|
|
84
|
+
Write-Info "$Bin not yet installed — starting fresh install"
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# ── Node.js ───────────────────────────────────────────────────────────────────
|
|
24
88
|
Write-Step "Checking Node.js"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Write-
|
|
28
|
-
|
|
29
|
-
Write-
|
|
89
|
+
|
|
90
|
+
if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
|
|
91
|
+
Write-Warn "Node.js not found."
|
|
92
|
+
Write-Host " Install from https://nodejs.org (LTS recommended)" -ForegroundColor DarkGray
|
|
93
|
+
Write-Host " Or via winget: winget install OpenJS.NodeJS.LTS" -ForegroundColor DarkGray
|
|
94
|
+
Write-Fail "Node.js $RequiredNodeMajor+ required."
|
|
30
95
|
}
|
|
31
96
|
|
|
32
|
-
|
|
97
|
+
$nodeVer = (node --version).TrimStart('v')
|
|
98
|
+
$nodeMajor = [int]($nodeVer -split '\.')[0]
|
|
99
|
+
|
|
100
|
+
if ($nodeMajor -lt $RequiredNodeMajor) {
|
|
101
|
+
Write-Fail "Node.js $RequiredNodeMajor+ required (got v$nodeVer). Upgrade: https://nodejs.org"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
Write-Ok "Node.js v$nodeVer"
|
|
105
|
+
|
|
106
|
+
# ── npm ───────────────────────────────────────────────────────────────────────
|
|
33
107
|
Write-Step "Checking npm"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Write-
|
|
37
|
-
} catch {
|
|
38
|
-
Write-Fail "npm not found."
|
|
108
|
+
|
|
109
|
+
if (-not (Get-Command npm -ErrorAction SilentlyContinue)) {
|
|
110
|
+
Write-Fail "npm not found. Reinstall Node.js from https://nodejs.org"
|
|
39
111
|
}
|
|
40
112
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
113
|
+
Write-Ok "npm $(npm --version)"
|
|
114
|
+
|
|
115
|
+
# ── Install ───────────────────────────────────────────────────────────────────
|
|
116
|
+
Write-Step "Installing ${Package}@${Tag}"
|
|
117
|
+
Write-Info "Running: npm install -g ${Package}@${Tag}"
|
|
118
|
+
Write-Host ""
|
|
119
|
+
|
|
120
|
+
npm install -g "${Package}@${Tag}" 2>&1 | Where-Object { $_ -notmatch "^npm warn" -and $_.Trim() -ne "" }
|
|
121
|
+
|
|
122
|
+
Write-Host ""
|
|
44
123
|
Write-Ok "$Package installed"
|
|
45
124
|
|
|
46
|
-
# Verify
|
|
125
|
+
# ── Verify ────────────────────────────────────────────────────────────────────
|
|
47
126
|
Write-Step "Verifying"
|
|
127
|
+
|
|
48
128
|
try {
|
|
49
129
|
$binPath = (Get-Command $Bin -ErrorAction Stop).Path
|
|
50
|
-
Write-Ok "$Bin
|
|
130
|
+
Write-Ok "$Bin → $binPath"
|
|
51
131
|
} catch {
|
|
52
|
-
Write-Warn "$Bin not found in PATH.
|
|
132
|
+
Write-Warn "$Bin not found in PATH. Restart your terminal and try again."
|
|
53
133
|
}
|
|
54
134
|
|
|
55
|
-
# Platform tools
|
|
135
|
+
# ── Platform tools ────────────────────────────────────────────────────────────
|
|
56
136
|
Write-Step "Checking platform-specific tools"
|
|
57
137
|
|
|
58
138
|
if (Get-Command "ares-setup-device" -ErrorAction SilentlyContinue) {
|
|
59
139
|
Write-Ok "ares-cli (LG webOS) found"
|
|
60
140
|
} else {
|
|
61
|
-
Write-Warn "ares-cli not found
|
|
141
|
+
Write-Warn "ares-cli not found → npm install -g @webosose/ares-cli"
|
|
62
142
|
}
|
|
63
143
|
|
|
64
144
|
if (Get-Command "sdb" -ErrorAction SilentlyContinue) {
|
|
65
145
|
Write-Ok "sdb (Samsung Tizen) found"
|
|
66
146
|
} else {
|
|
67
|
-
Write-Warn "sdb not found
|
|
147
|
+
Write-Warn "sdb not found → install Tizen Studio: developer.samsung.com/smarttv"
|
|
68
148
|
}
|
|
69
149
|
|
|
70
150
|
if (Get-Command "adb" -ErrorAction SilentlyContinue) {
|
|
71
|
-
Write-Ok "adb (
|
|
151
|
+
Write-Ok "adb (Fire TV / Android TV) found"
|
|
72
152
|
} else {
|
|
73
|
-
Write-Warn "adb not found
|
|
153
|
+
Write-Warn "adb not found → install Android SDK Platform Tools"
|
|
74
154
|
}
|
|
75
155
|
|
|
156
|
+
if (Get-Command "inputd-cli" -ErrorAction SilentlyContinue) {
|
|
157
|
+
Write-Ok "inputd-cli (Fire TV input) found"
|
|
158
|
+
} else {
|
|
159
|
+
Write-Warn "inputd-cli not found (optional — Fire TV remote input simulation)"
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
# ── Done ──────────────────────────────────────────────────────────────────────
|
|
76
163
|
Write-Host ""
|
|
77
164
|
Write-Host " Installation complete!" -ForegroundColor Green
|
|
78
165
|
Write-Host ""
|
|
79
166
|
Write-Host " Launch TV Dev Manager: " -NoNewline
|
|
80
167
|
Write-Host $Bin -ForegroundColor Cyan
|
|
81
168
|
Write-Host ""
|
|
169
|
+
Write-Host " GitHub : https://github.com/tvdev-cli/tvdev-cli" -ForegroundColor DarkGray
|
|
170
|
+
Write-Host " npm : https://npmjs.com/package/unified-tvdevelopment-cli" -ForegroundColor DarkGray
|
|
171
|
+
Write-Host ""
|
package/install.sh
CHANGED
|
@@ -1,17 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
#
|
|
2
|
+
# tvdev-cli — one-line installer
|
|
3
|
+
# Pulls the latest release binary directly from GitHub Releases.
|
|
4
4
|
#
|
|
5
|
-
# curl -fsSL https://raw.githubusercontent.com/
|
|
5
|
+
# curl -fsSL https://raw.githubusercontent.com/tvdev-cli/tvdev-cli/main/install.sh | bash
|
|
6
|
+
# curl -fsSL https://raw.githubusercontent.com/tvdev-cli/tvdev-cli/main/install.sh | bash -s -- --beta
|
|
6
7
|
#
|
|
7
8
|
set -euo pipefail
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
REPO="tvdev-cli/tvdev-cli"
|
|
10
11
|
BIN="tvdev"
|
|
11
12
|
REQUIRED_NODE=18
|
|
12
13
|
NVM_VERSION="v0.39.7"
|
|
13
14
|
INSTALL_NODE_VERSION="20"
|
|
15
|
+
CHANNEL="stable" # stable | beta
|
|
14
16
|
|
|
17
|
+
# ── Flags ─────────────────────────────────────────────────────────────────────
|
|
18
|
+
for arg in "${@:-}"; do
|
|
19
|
+
case "$arg" in
|
|
20
|
+
--beta) CHANNEL="beta" ;;
|
|
21
|
+
esac
|
|
22
|
+
done
|
|
23
|
+
|
|
24
|
+
# ── Colors ────────────────────────────────────────────────────────────────────
|
|
15
25
|
if [ -t 1 ]; then
|
|
16
26
|
INDIGO='\033[38;5;99m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
|
|
17
27
|
RED='\033[0;31m'; BOLD='\033[1m'; DIM='\033[2m'; RESET='\033[0m'
|
|
@@ -19,12 +29,16 @@ else
|
|
|
19
29
|
INDIGO=''; GREEN=''; YELLOW=''; RED=''; BOLD=''; DIM=''; RESET=''
|
|
20
30
|
fi
|
|
21
31
|
|
|
32
|
+
# ── Helpers ───────────────────────────────────────────────────────────────────
|
|
22
33
|
banner() {
|
|
23
34
|
echo ""
|
|
24
35
|
echo -e "${BOLD}${INDIGO} ◉ TV Dev Manager${RESET}"
|
|
25
36
|
echo -e " ${INDIGO}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
|
|
26
37
|
echo -e " ${DIM}Universal Smart TV Development CLI${RESET}"
|
|
27
38
|
echo -e " ${DIM}LG webOS · Samsung Tizen · Amazon Fire TV · Android TV${RESET}"
|
|
39
|
+
if [ "$CHANNEL" = "beta" ]; then
|
|
40
|
+
echo -e " ${YELLOW} channel: beta${RESET}"
|
|
41
|
+
fi
|
|
28
42
|
echo ""
|
|
29
43
|
}
|
|
30
44
|
|
|
@@ -32,69 +46,76 @@ 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"
|
|
60
|
+
*/zsh) echo "$HOME/.zshrc" ;;
|
|
41
61
|
*/bash)
|
|
42
|
-
[ -f "$HOME/.bash_profile" ] && echo "$HOME/.bash_profile" || echo "$HOME/.bashrc"
|
|
43
|
-
;;
|
|
62
|
+
[ -f "$HOME/.bash_profile" ] && echo "$HOME/.bash_profile" || echo "$HOME/.bashrc" ;;
|
|
44
63
|
*/fish) echo "$HOME/.config/fish/config.fish" ;;
|
|
45
64
|
*) echo "$HOME/.profile" ;;
|
|
46
65
|
esac
|
|
47
66
|
}
|
|
48
67
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if [[ "${SHELL:-}" == */fish ]]; then
|
|
60
|
-
export_line="set -gx PATH \$PATH ${bin_dir}"
|
|
68
|
+
# ── Resolve GitHub release ────────────────────────────────────────────────────
|
|
69
|
+
fetch_release_info() {
|
|
70
|
+
local url
|
|
71
|
+
if [ "$CHANNEL" = "beta" ]; then
|
|
72
|
+
# latest pre-release (first entry that has prerelease:true)
|
|
73
|
+
url="https://api.github.com/repos/${REPO}/releases"
|
|
74
|
+
curl -fsSL "$url" \
|
|
75
|
+
| grep -E '"tag_name"|"prerelease"' \
|
|
76
|
+
| paste - - \
|
|
77
|
+
| awk -F'"' '/"prerelease": true/{print $4; exit}'
|
|
61
78
|
else
|
|
62
|
-
|
|
79
|
+
# latest stable release
|
|
80
|
+
curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest" \
|
|
81
|
+
| grep '"tag_name"' \
|
|
82
|
+
| sed 's/.*"tag_name": *"\([^"]*\)".*/\1/'
|
|
63
83
|
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
|
|
68
|
-
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
84
|
}
|
|
76
85
|
|
|
77
|
-
# ──
|
|
86
|
+
# ── Banner ────────────────────────────────────────────────────────────────────
|
|
78
87
|
banner
|
|
79
88
|
|
|
89
|
+
# ── Resolve release tag ───────────────────────────────────────────────────────
|
|
90
|
+
step "Resolving latest ${CHANNEL} release from GitHub"
|
|
91
|
+
|
|
92
|
+
RELEASE_TAG=$(fetch_release_info)
|
|
93
|
+
[ -z "$RELEASE_TAG" ] && fail "Could not resolve release tag from GitHub. Check https://github.com/${REPO}/releases"
|
|
94
|
+
|
|
95
|
+
RELEASE_VERSION="${RELEASE_TAG#v}"
|
|
96
|
+
info "Release : ${RELEASE_TAG}"
|
|
97
|
+
|
|
98
|
+
# Download URL for the cli.mjs asset attached to the release
|
|
99
|
+
DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${RELEASE_TAG}/cli.mjs"
|
|
100
|
+
|
|
101
|
+
# ── Idempotency check ─────────────────────────────────────────────────────────
|
|
80
102
|
step "Checking existing installation"
|
|
81
103
|
|
|
104
|
+
INSTALLED_VER=""
|
|
82
105
|
if command -v "$BIN" &>/dev/null; then
|
|
83
|
-
INSTALLED_VER=$(
|
|
84
|
-
| grep "$PACKAGE" | sed 's/.*@//' | tr -d '[:space:]' || true)
|
|
85
|
-
LATEST_VER=$(npm show "$PACKAGE" version 2>/dev/null || true)
|
|
86
|
-
|
|
106
|
+
INSTALLED_VER=$("$BIN" --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+[^ ]*' | head -1 || true)
|
|
87
107
|
ok "${BIN} already installed"
|
|
88
108
|
[ -n "$INSTALLED_VER" ] && info "Installed : ${INSTALLED_VER}"
|
|
89
|
-
|
|
109
|
+
info "Latest : ${RELEASE_VERSION} (${CHANNEL})"
|
|
90
110
|
|
|
91
|
-
if [ -n "$INSTALLED_VER" ] &&
|
|
111
|
+
if [ -n "$INSTALLED_VER" ] && semver_gte "$INSTALLED_VER" "$RELEASE_VERSION"; then
|
|
92
112
|
ok "Already up to date — nothing to do"
|
|
93
113
|
echo ""
|
|
94
114
|
echo -e " ${BOLD}Run: ${INDIGO}${BIN}${RESET}"
|
|
95
115
|
echo ""
|
|
96
116
|
exit 0
|
|
97
117
|
fi
|
|
118
|
+
info "Update available — reinstalling"
|
|
98
119
|
else
|
|
99
120
|
info "${BIN} not yet installed — starting fresh install"
|
|
100
121
|
fi
|
|
@@ -107,7 +128,7 @@ install_node_via_nvm() {
|
|
|
107
128
|
export NVM_DIR="${HOME}/.nvm"
|
|
108
129
|
curl -fsSL "https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh" | bash
|
|
109
130
|
[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"
|
|
110
|
-
nvm install "$INSTALL_NODE_VERSION"
|
|
131
|
+
nvm install "$INSTALL_NODE_VERSION"
|
|
111
132
|
nvm use "$INSTALL_NODE_VERSION"
|
|
112
133
|
nvm alias default "$INSTALL_NODE_VERSION"
|
|
113
134
|
ok "Node.js $(node --version) installed via nvm"
|
|
@@ -117,7 +138,9 @@ if ! command -v node &>/dev/null; then
|
|
|
117
138
|
NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
|
|
118
139
|
if [ -s "$NVM_DIR/nvm.sh" ]; then
|
|
119
140
|
source "$NVM_DIR/nvm.sh"
|
|
120
|
-
if ! command -v node &>/dev/null; then
|
|
141
|
+
if ! command -v node &>/dev/null; then
|
|
142
|
+
nvm install "$INSTALL_NODE_VERSION" && nvm use "$INSTALL_NODE_VERSION"
|
|
143
|
+
fi
|
|
121
144
|
else
|
|
122
145
|
install_node_via_nvm
|
|
123
146
|
fi
|
|
@@ -126,33 +149,61 @@ fi
|
|
|
126
149
|
! command -v node &>/dev/null && fail "Node.js install failed. Install manually: https://nodejs.org"
|
|
127
150
|
|
|
128
151
|
NODE_MAJOR=$(node --version | sed 's/v//' | cut -d. -f1)
|
|
129
|
-
[ "$NODE_MAJOR" -lt "$REQUIRED_NODE" ] &&
|
|
152
|
+
[ "$NODE_MAJOR" -lt "$REQUIRED_NODE" ] && \
|
|
153
|
+
fail "Node.js ${REQUIRED_NODE}+ required (got $(node --version)). Upgrade: https://nodejs.org"
|
|
130
154
|
|
|
131
155
|
ok "Node.js $(node --version)"
|
|
132
156
|
|
|
133
|
-
# ──
|
|
134
|
-
step "
|
|
135
|
-
|
|
136
|
-
ok "npm $(npm --version)"
|
|
157
|
+
# ── Download & install binary from GitHub Release ────────────────────────────
|
|
158
|
+
step "Downloading ${BIN} ${RELEASE_TAG} from GitHub"
|
|
159
|
+
info "Source: ${DOWNLOAD_URL}"
|
|
137
160
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
ok "${
|
|
161
|
+
INSTALL_DIR="${HOME}/.local/bin"
|
|
162
|
+
mkdir -p "$INSTALL_DIR"
|
|
163
|
+
BIN_PATH="${INSTALL_DIR}/${BIN}"
|
|
164
|
+
|
|
165
|
+
if curl -fsSL --output "$BIN_PATH" "$DOWNLOAD_URL"; then
|
|
166
|
+
chmod +x "$BIN_PATH"
|
|
167
|
+
ok "Installed to ${BIN_PATH}"
|
|
168
|
+
else
|
|
169
|
+
# fallback: try npm if GitHub download fails
|
|
170
|
+
warn "GitHub download failed — falling back to npm"
|
|
171
|
+
! command -v npm &>/dev/null && fail "npm not found. 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
|
+
fi
|
|
145
176
|
|
|
146
177
|
# ── PATH ──────────────────────────────────────────────────────────────────────
|
|
147
178
|
step "Setting up PATH"
|
|
148
|
-
|
|
179
|
+
|
|
180
|
+
rc_file=$(detect_shell_rc)
|
|
181
|
+
export_line="export PATH=\"\$PATH:${INSTALL_DIR}\""
|
|
182
|
+
|
|
183
|
+
if echo ":${PATH}:" | grep -q ":${INSTALL_DIR}:"; then
|
|
184
|
+
ok "PATH already contains ${INSTALL_DIR}"
|
|
185
|
+
elif [[ "${SHELL:-}" == */fish ]]; then
|
|
186
|
+
echo "set -gx PATH \$PATH ${INSTALL_DIR}" >> "$rc_file"
|
|
187
|
+
ok "Added PATH entry to ${rc_file}"
|
|
188
|
+
else
|
|
189
|
+
if ! grep -qF "$INSTALL_DIR" "$rc_file" 2>/dev/null; then
|
|
190
|
+
echo "" >> "$rc_file"
|
|
191
|
+
echo "# added by tvdev-cli installer" >> "$rc_file"
|
|
192
|
+
echo "$export_line" >> "$rc_file"
|
|
193
|
+
ok "Added PATH entry to ${rc_file}"
|
|
194
|
+
else
|
|
195
|
+
ok "PATH entry already in ${rc_file}"
|
|
196
|
+
fi
|
|
197
|
+
export PATH="${PATH}:${INSTALL_DIR}"
|
|
198
|
+
fi
|
|
199
|
+
|
|
149
200
|
hash -r 2>/dev/null || true
|
|
150
201
|
|
|
151
202
|
if command -v "$BIN" &>/dev/null; then
|
|
152
203
|
ok "${BIN} is in PATH → $(command -v ${BIN})"
|
|
153
204
|
else
|
|
154
|
-
warn "${BIN} not in PATH for this session. Restart
|
|
155
|
-
echo -e "\n
|
|
205
|
+
warn "${BIN} not in PATH for this session. Restart terminal or:"
|
|
206
|
+
echo -e "\n source $(detect_shell_rc)\n"
|
|
156
207
|
fi
|
|
157
208
|
|
|
158
209
|
# ── Platform tools ────────────────────────────────────────────────────────────
|
|
@@ -161,34 +212,34 @@ step "Checking platform-specific tools"
|
|
|
161
212
|
if command -v ares-setup-device &>/dev/null; then
|
|
162
213
|
ok "ares-cli (LG webOS) → $(command -v ares-setup-device)"
|
|
163
214
|
else
|
|
164
|
-
warn "ares-cli not found
|
|
215
|
+
warn "ares-cli not found → npm install -g @webosose/ares-cli"
|
|
165
216
|
fi
|
|
166
217
|
|
|
167
218
|
if command -v sdb &>/dev/null; then
|
|
168
219
|
ok "sdb (Samsung Tizen) → $(command -v sdb)"
|
|
169
220
|
else
|
|
170
|
-
warn "sdb not found
|
|
221
|
+
warn "sdb not found → install Tizen Studio: developer.samsung.com/smarttv"
|
|
171
222
|
fi
|
|
172
223
|
|
|
173
224
|
if command -v adb &>/dev/null; then
|
|
174
|
-
ok "adb (
|
|
225
|
+
ok "adb (Fire TV / Android TV) → $(command -v adb)"
|
|
175
226
|
else
|
|
176
|
-
warn "adb not found
|
|
227
|
+
warn "adb not found → brew install android-platform-tools"
|
|
177
228
|
fi
|
|
178
229
|
|
|
179
230
|
if command -v inputd-cli &>/dev/null; then
|
|
180
|
-
ok "inputd-cli (
|
|
231
|
+
ok "inputd-cli (Fire TV input) → $(command -v inputd-cli)"
|
|
181
232
|
else
|
|
182
|
-
warn "inputd-cli not found (optional —
|
|
233
|
+
warn "inputd-cli not found (optional — Fire TV remote input simulation)"
|
|
183
234
|
fi
|
|
184
235
|
|
|
185
236
|
# ── Done ──────────────────────────────────────────────────────────────────────
|
|
186
237
|
echo ""
|
|
187
238
|
echo -e "${BOLD}${INDIGO} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
|
|
188
|
-
echo -e "${BOLD}${GREEN} ✓ Installation complete
|
|
239
|
+
echo -e "${BOLD}${GREEN} ✓ Installation complete! (${RELEASE_TAG})${RESET}"
|
|
189
240
|
echo ""
|
|
190
241
|
echo -e " Launch TV Dev Manager: ${BOLD}${INDIGO}${BIN}${RESET}"
|
|
191
242
|
echo ""
|
|
192
|
-
echo -e " ${DIM}GitHub : https://github.com/
|
|
243
|
+
echo -e " ${DIM}GitHub : https://github.com/tvdev-cli/tvdev-cli${RESET}"
|
|
193
244
|
echo -e " ${DIM}npm : https://npmjs.com/package/unified-tvdevelopment-cli${RESET}"
|
|
194
245
|
echo ""
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unified-tvdevelopment-cli",
|
|
3
|
-
"version": "1.0.1
|
|
3
|
+
"version": "1.0.1",
|
|
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 --
|
|
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/
|
|
42
|
+
"url": "git+https://github.com/tvdev-cli/tvdev-cli.git"
|
|
43
43
|
},
|
|
44
44
|
"files": [
|
|
45
45
|
"dist/",
|