unified-tvdevelopment-cli 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,37 @@
1
+ # Release Process
2
+
3
+ ## Quick release
4
+
5
+ ```bash
6
+ npm version patch # or minor / major
7
+ git push origin main --follow-tags
8
+ ```
9
+
10
+ The `npm version` command:
11
+ 1. Updates `package.json` version
12
+ 2. Creates a git commit (`chore(release): vX.Y.Z`)
13
+ 3. Creates a git tag (`vX.Y.Z`)
14
+
15
+ Pushing the tag triggers the `release.yml` workflow which:
16
+ - Runs tests
17
+ - Validates tag matches `package.json`
18
+ - Publishes to npm
19
+ - Creates a GitHub Release
20
+
21
+ ## Pre-releases (beta)
22
+
23
+ ```bash
24
+ npm version prerelease --preid=beta # e.g. 1.0.1-beta.0
25
+ git push origin main --follow-tags
26
+ ```
27
+
28
+ Beta releases publish to npm with `--tag beta` and are marked as pre-release on GitHub.
29
+
30
+ ## Platform CLI dependencies
31
+
32
+ | Platform | Required tools |
33
+ |---|---|
34
+ | LG webOS | `npm install -g @webosose/ares-cli` |
35
+ | Samsung Tizen | Tizen Studio (tizen + sdb) |
36
+ | Amazon Fire TV | `adb` (Android Platform Tools) + `inputd-cli` + `LoggingCtl` |
37
+ | Android TV | Android SDK (`adb`, `gradle`, `avdmanager`, `emulator`) |
package/install.ps1 ADDED
@@ -0,0 +1,171 @@
1
+ # unified-tvdevelopment-cli — Windows installer
2
+ # Run:
3
+ # iwr -useb https://raw.githubusercontent.com/FernandoHaeser/unified-tvdevelopment-cli/main/install.ps1 | iex
4
+ # iwr -useb https://raw.githubusercontent.com/FernandoHaeser/unified-tvdevelopment-cli/main/install.ps1 | iex # then pass -Beta
5
+
6
+ param(
7
+ [switch]$Beta,
8
+ [string]$Tag = "latest"
9
+ )
10
+
11
+ $ErrorActionPreference = 'Stop'
12
+ $Package = "unified-tvdevelopment-cli"
13
+ $Bin = "tvdev"
14
+ $RequiredNodeMajor = 18
15
+
16
+ if ($Beta) { $Tag = "beta" }
17
+
18
+ # ── Helpers ───────────────────────────────────────────────────────────────────
19
+ function Write-Banner {
20
+ Write-Host ""
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
+ }
27
+ Write-Host " Universal Smart TV Development CLI" -ForegroundColor DarkGray
28
+ Write-Host " LG webOS · Samsung Tizen · Amazon Fire TV · Android TV" -ForegroundColor DarkGray
29
+ Write-Host ""
30
+ }
31
+
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
+ }
56
+
57
+ Write-Banner
58
+
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 ───────────────────────────────────────────────────────────────────
88
+ Write-Step "Checking Node.js"
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."
95
+ }
96
+
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 ───────────────────────────────────────────────────────────────────────
107
+ Write-Step "Checking npm"
108
+
109
+ if (-not (Get-Command npm -ErrorAction SilentlyContinue)) {
110
+ Write-Fail "npm not found. Reinstall Node.js from https://nodejs.org"
111
+ }
112
+
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 ""
123
+ Write-Ok "$Package installed"
124
+
125
+ # ── Verify ────────────────────────────────────────────────────────────────────
126
+ Write-Step "Verifying"
127
+
128
+ try {
129
+ $binPath = (Get-Command $Bin -ErrorAction Stop).Path
130
+ Write-Ok "$Bin → $binPath"
131
+ } catch {
132
+ Write-Warn "$Bin not found in PATH. Restart your terminal and try again."
133
+ }
134
+
135
+ # ── Platform tools ────────────────────────────────────────────────────────────
136
+ Write-Step "Checking platform-specific tools"
137
+
138
+ if (Get-Command "ares-setup-device" -ErrorAction SilentlyContinue) {
139
+ Write-Ok "ares-cli (LG webOS) found"
140
+ } else {
141
+ Write-Warn "ares-cli not found → npm install -g @webosose/ares-cli"
142
+ }
143
+
144
+ if (Get-Command "sdb" -ErrorAction SilentlyContinue) {
145
+ Write-Ok "sdb (Samsung Tizen) found"
146
+ } else {
147
+ Write-Warn "sdb not found → install Tizen Studio: developer.samsung.com/smarttv"
148
+ }
149
+
150
+ if (Get-Command "adb" -ErrorAction SilentlyContinue) {
151
+ Write-Ok "adb (Fire TV / Android TV) found"
152
+ } else {
153
+ Write-Warn "adb not found → install Android SDK Platform Tools"
154
+ }
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 ──────────────────────────────────────────────────────────────────────
163
+ Write-Host ""
164
+ Write-Host " Installation complete!" -ForegroundColor Green
165
+ Write-Host ""
166
+ Write-Host " Launch TV Dev Manager: " -NoNewline
167
+ Write-Host $Bin -ForegroundColor Cyan
168
+ Write-Host ""
169
+ Write-Host " GitHub : https://github.com/FernandoHaeser/unified-tvdevelopment-cli" -ForegroundColor DarkGray
170
+ Write-Host " npm : https://npmjs.com/package/unified-tvdevelopment-cli" -ForegroundColor DarkGray
171
+ Write-Host ""
package/install.sh ADDED
@@ -0,0 +1,226 @@
1
+ #!/usr/bin/env bash
2
+ # unified-tvdevelopment-cli — one-line installer
3
+ # Supports: LG webOS, Samsung Tizen, Amazon Fire TV, Android TV
4
+ #
5
+ # curl -fsSL https://raw.githubusercontent.com/FernandoHaeser/unified-tvdevelopment-cli/main/install.sh | bash
6
+ # curl -fsSL https://raw.githubusercontent.com/FernandoHaeser/unified-tvdevelopment-cli/main/install.sh | bash -s -- --beta
7
+ #
8
+ set -euo pipefail
9
+
10
+ PACKAGE="unified-tvdevelopment-cli"
11
+ BIN="tvdev"
12
+ REQUIRED_NODE=18
13
+ NVM_VERSION="v0.39.7"
14
+ INSTALL_NODE_VERSION="20"
15
+ NPM_TAG="latest"
16
+
17
+ # ── Flags ─────────────────────────────────────────────────────────────────────
18
+ for arg in "${@:-}"; do
19
+ case "$arg" in
20
+ --beta) NPM_TAG="beta" ;;
21
+ --tag=*) NPM_TAG="${arg#--tag=}" ;;
22
+ --tag) shift; NPM_TAG="${1:-latest}" ;;
23
+ esac
24
+ done
25
+
26
+ # ── Colors ────────────────────────────────────────────────────────────────────
27
+ if [ -t 1 ]; then
28
+ INDIGO='\033[38;5;99m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
29
+ RED='\033[0;31m'; BOLD='\033[1m'; DIM='\033[2m'; RESET='\033[0m'
30
+ else
31
+ INDIGO=''; GREEN=''; YELLOW=''; RED=''; BOLD=''; DIM=''; RESET=''
32
+ fi
33
+
34
+ # ── Helpers ───────────────────────────────────────────────────────────────────
35
+ banner() {
36
+ echo ""
37
+ echo -e "${BOLD}${INDIGO} ◉ TV Dev Manager${RESET}"
38
+ echo -e " ${INDIGO}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
39
+ echo -e " ${DIM}Universal Smart TV Development CLI${RESET}"
40
+ echo -e " ${DIM}LG webOS · Samsung Tizen · Amazon Fire TV · Android TV${RESET}"
41
+ if [ "$NPM_TAG" != "latest" ]; then
42
+ echo -e " ${YELLOW} tag: ${NPM_TAG}${RESET}"
43
+ fi
44
+ echo ""
45
+ }
46
+
47
+ step() { echo -e "\n${BOLD}${INDIGO} ▶ $*${RESET}"; }
48
+ ok() { echo -e " ${GREEN}✓${RESET} $*"; }
49
+ info() { echo -e " ${INDIGO}●${RESET} $*"; }
50
+ warn() { echo -e " ${YELLOW}⚠${RESET} $*"; }
51
+ fail() { echo -e "\n ${RED}✗ $*${RESET}\n"; exit 1; }
52
+
53
+ # ── Semver compare (returns 0 if $1 >= $2) ────────────────────────────────────
54
+ semver_gte() {
55
+ # strip pre-release suffix for comparison
56
+ local a b
57
+ a=$(echo "$1" | sed 's/-.*//')
58
+ b=$(echo "$2" | sed 's/-//')
59
+ [ "$(printf '%s\n%s\n' "$a" "$b" | sort -V | head -1)" = "$b" ]
60
+ }
61
+
62
+ detect_shell_rc() {
63
+ case "${SHELL:-}" in
64
+ */zsh) echo "$HOME/.zshrc" ;;
65
+ */bash)
66
+ [ -f "$HOME/.bash_profile" ] && echo "$HOME/.bash_profile" || echo "$HOME/.bashrc"
67
+ ;;
68
+ */fish) echo "$HOME/.config/fish/config.fish" ;;
69
+ *) echo "$HOME/.profile" ;;
70
+ esac
71
+ }
72
+
73
+ idempotent_path_export() {
74
+ local bin_dir rc_file export_line
75
+ bin_dir=$(npm prefix -g 2>/dev/null)/bin
76
+ rc_file=$(detect_shell_rc)
77
+
78
+ if echo ":${PATH}:" | grep -q ":${bin_dir}:"; then
79
+ ok "PATH already contains npm global bin"
80
+ return
81
+ fi
82
+
83
+ if [[ "${SHELL:-}" == */fish ]]; then
84
+ export_line="set -gx PATH \$PATH ${bin_dir}"
85
+ else
86
+ export_line="export PATH=\"\$PATH:${bin_dir}\""
87
+ fi
88
+
89
+ if [ -f "$rc_file" ] && grep -qF "$bin_dir" "$rc_file" 2>/dev/null; then
90
+ ok "PATH entry already in ${rc_file}"
91
+ return
92
+ fi
93
+
94
+ echo "" >> "$rc_file"
95
+ echo "# added by unified-tvdevelopment-cli installer" >> "$rc_file"
96
+ echo "$export_line" >> "$rc_file"
97
+ ok "Added PATH entry to ${rc_file}"
98
+ export PATH="${PATH}:${bin_dir}"
99
+ }
100
+
101
+ # ── Idempotency check ─────────────────────────────────────────────────────────
102
+ banner
103
+
104
+ step "Checking existing installation"
105
+
106
+ INSTALLED_VER=""
107
+ LATEST_VER=""
108
+
109
+ if command -v "$BIN" &>/dev/null; then
110
+ INSTALLED_VER=$(npm list -g --depth=0 "$PACKAGE" 2>/dev/null \
111
+ | grep "$PACKAGE" | sed 's/.*@//' | tr -d '[:space:]' || true)
112
+ LATEST_VER=$(npm show "${PACKAGE}@${NPM_TAG}" version 2>/dev/null || true)
113
+
114
+ ok "${BIN} already installed"
115
+ [ -n "$INSTALLED_VER" ] && info "Installed : ${INSTALLED_VER}"
116
+ [ -n "$LATEST_VER" ] && info "Latest : ${LATEST_VER} (${NPM_TAG})"
117
+
118
+ if [ -n "$INSTALLED_VER" ] && [ -n "$LATEST_VER" ] && semver_gte "$INSTALLED_VER" "$LATEST_VER"; then
119
+ ok "Already up to date — nothing to do"
120
+ echo ""
121
+ echo -e " ${BOLD}Run: ${INDIGO}${BIN}${RESET}"
122
+ echo ""
123
+ exit 0
124
+ fi
125
+
126
+ info "Update available — reinstalling"
127
+ else
128
+ info "${BIN} not yet installed — starting fresh install"
129
+ fi
130
+
131
+ # ── Node.js ───────────────────────────────────────────────────────────────────
132
+ step "Checking Node.js"
133
+
134
+ install_node_via_nvm() {
135
+ warn "Node.js not found — installing via nvm"
136
+ export NVM_DIR="${HOME}/.nvm"
137
+ curl -fsSL "https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh" | bash
138
+ [ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"
139
+ nvm install "$INSTALL_NODE_VERSION"
140
+ nvm use "$INSTALL_NODE_VERSION"
141
+ nvm alias default "$INSTALL_NODE_VERSION"
142
+ ok "Node.js $(node --version) installed via nvm"
143
+ }
144
+
145
+ if ! command -v node &>/dev/null; then
146
+ NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
147
+ if [ -s "$NVM_DIR/nvm.sh" ]; then
148
+ source "$NVM_DIR/nvm.sh"
149
+ if ! command -v node &>/dev/null; then
150
+ nvm install "$INSTALL_NODE_VERSION" && nvm use "$INSTALL_NODE_VERSION"
151
+ fi
152
+ else
153
+ install_node_via_nvm
154
+ fi
155
+ fi
156
+
157
+ ! command -v node &>/dev/null && fail "Node.js install failed. Install manually: https://nodejs.org"
158
+
159
+ NODE_MAJOR=$(node --version | sed 's/v//' | cut -d. -f1)
160
+ [ "$NODE_MAJOR" -lt "$REQUIRED_NODE" ] && \
161
+ fail "Node.js ${REQUIRED_NODE}+ required (got $(node --version)). Upgrade: https://nodejs.org"
162
+
163
+ ok "Node.js $(node --version)"
164
+
165
+ # ── npm ───────────────────────────────────────────────────────────────────────
166
+ step "Checking npm"
167
+ ! command -v npm &>/dev/null && fail "npm not found."
168
+ ok "npm $(npm --version)"
169
+
170
+ # ── Install ───────────────────────────────────────────────────────────────────
171
+ step "Installing ${PACKAGE}@${NPM_TAG}"
172
+ info "Running: npm install -g ${PACKAGE}@${NPM_TAG}"
173
+ echo ""
174
+ npm install -g "${PACKAGE}@${NPM_TAG}" 2>&1 | grep -v "^npm warn" | grep -v "^$" || true
175
+ echo ""
176
+ ok "${PACKAGE} installed"
177
+
178
+ # ── PATH ──────────────────────────────────────────────────────────────────────
179
+ step "Setting up PATH"
180
+ idempotent_path_export
181
+ hash -r 2>/dev/null || true
182
+
183
+ if command -v "$BIN" &>/dev/null; then
184
+ ok "${BIN} is in PATH → $(command -v ${BIN})"
185
+ else
186
+ warn "${BIN} not in PATH for this session. Restart terminal or:"
187
+ echo -e "\n source $(detect_shell_rc)\n"
188
+ fi
189
+
190
+ # ── Platform tools ────────────────────────────────────────────────────────────
191
+ step "Checking platform-specific tools"
192
+
193
+ if command -v ares-setup-device &>/dev/null; then
194
+ ok "ares-cli (LG webOS) → $(command -v ares-setup-device)"
195
+ else
196
+ warn "ares-cli not found → npm install -g @webosose/ares-cli"
197
+ fi
198
+
199
+ if command -v sdb &>/dev/null; then
200
+ ok "sdb (Samsung Tizen) → $(command -v sdb)"
201
+ else
202
+ warn "sdb not found → install Tizen Studio: developer.samsung.com/smarttv"
203
+ fi
204
+
205
+ if command -v adb &>/dev/null; then
206
+ ok "adb (Fire TV / Android TV) → $(command -v adb)"
207
+ else
208
+ warn "adb not found → brew install android-platform-tools (or Android Studio SDK)"
209
+ fi
210
+
211
+ if command -v inputd-cli &>/dev/null; then
212
+ ok "inputd-cli (Fire TV input) → $(command -v inputd-cli)"
213
+ else
214
+ warn "inputd-cli not found (optional — Fire TV remote input simulation)"
215
+ fi
216
+
217
+ # ── Done ──────────────────────────────────────────────────────────────────────
218
+ echo ""
219
+ echo -e "${BOLD}${INDIGO} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
220
+ echo -e "${BOLD}${GREEN} ✓ Installation complete!${RESET}"
221
+ echo ""
222
+ echo -e " Launch TV Dev Manager: ${BOLD}${INDIGO}${BIN}${RESET}"
223
+ echo ""
224
+ echo -e " ${DIM}GitHub : https://github.com/FernandoHaeser/unified-tvdevelopment-cli${RESET}"
225
+ echo -e " ${DIM}npm : https://npmjs.com/package/unified-tvdevelopment-cli${RESET}"
226
+ echo ""
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "unified-tvdevelopment-cli",
3
+ "version": "1.0.0",
4
+ "description": "Universal TUI manager for Smart TV development — LG webOS, Samsung Tizen, Amazon Fire TV, Android TV",
5
+ "type": "module",
6
+ "bin": {
7
+ "tvdev": "dist/cli.mjs"
8
+ },
9
+ "engines": {
10
+ "node": ">=18.0.0"
11
+ },
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",
14
+ "start": "npm run build && node dist/cli.mjs",
15
+ "dev": "npm run build && node dist/cli.mjs",
16
+ "prepare": "npm run build",
17
+ "test": "vitest run",
18
+ "test:unit": "vitest run tests/unit",
19
+ "test:integration": "vitest run tests/integration",
20
+ "test:e2e": "vitest run tests/e2e",
21
+ "test:watch": "vitest",
22
+ "test:coverage": "vitest run --coverage"
23
+ },
24
+ "keywords": [
25
+ "webos",
26
+ "tizen",
27
+ "android-tv",
28
+ "fire-tv",
29
+ "amazon",
30
+ "ares-cli",
31
+ "sdb",
32
+ "adb",
33
+ "tui",
34
+ "cli",
35
+ "smart-tv",
36
+ "lg",
37
+ "samsung"
38
+ ],
39
+ "license": "MIT",
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "git+https://github.com/tvdev-cli/unified-tvdevelopment-cli.git"
43
+ },
44
+ "files": [
45
+ "dist/",
46
+ "install.sh",
47
+ "install.ps1",
48
+ "README.md",
49
+ "docs/"
50
+ ],
51
+ "dependencies": {
52
+ "chalk": "^5.3.0",
53
+ "execa": "^9.3.0",
54
+ "ink": "^5.0.1",
55
+ "ink-text-input": "^6.0.0",
56
+ "react": "^18.3.1"
57
+ },
58
+ "devDependencies": {
59
+ "@vitest/coverage-v8": "^2.1.9",
60
+ "esbuild": "^0.28.0",
61
+ "vitest": "^2.1.9"
62
+ }
63
+ }