From fc0ddd28e1cd99a639c6d901d63d34a668fd5ea7 Mon Sep 17 00:00:00 2001 From: Lalit Gupta Date: Thu, 26 Mar 2026 20:41:27 +0530 Subject: [PATCH] fix: downgrade fix-path to v4 for CJS compat, lowercase productName, add install script - fix-path v5 is ESM-only which breaks CJS build (TS2307) - Lowercase productName + CFBundleDisplayName for consistent branding - Add artifactName with arch suffix for DMG naming - Add install script for curl-based installation - Add publish.sh to .gitignore --- .gitignore | 3 + electron-builder.config.js | 13 ++-- install | 128 +++++++++++++++++++++++++++++++++++++ package-lock.json | 40 ++---------- package.json | 2 +- 5 files changed, 146 insertions(+), 40 deletions(-) create mode 100644 install diff --git a/.gitignore b/.gitignore index 9ec845a..aa57089 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ auth_config.json # TypeScript cache *.tsbuildinfo + +# Publish script +publish.sh diff --git a/electron-builder.config.js b/electron-builder.config.js index cd47b96..3fc7fdc 100644 --- a/electron-builder.config.js +++ b/electron-builder.config.js @@ -17,7 +17,7 @@ function getTargetArchName(arch) { */ const config = { appId: 'com.videodb.call-md', - productName: 'Call.md', + productName: 'call.md', directories: { output: 'release', buildResources: 'resources', @@ -58,6 +58,7 @@ const config = { arch: ['x64', 'arm64'], }, ], + artifactName: 'call.md-${version}-${arch}.${ext}', category: 'public.app-category.productivity', icon: 'resources/icon.icns', hardenedRuntime: true, @@ -65,14 +66,16 @@ const config = { entitlements: 'build/entitlements.mac.plist', entitlementsInherit: 'build/entitlements.mac.plist', extendInfo: { - NSMicrophoneUsageDescription: 'Call.md needs microphone access to record audio.', - NSCameraUsageDescription: 'Call.md needs camera access to record video.', + CFBundleDisplayName: 'call.md', + CFBundleName: 'call.md', + NSMicrophoneUsageDescription: 'call.md needs microphone access to record audio.', + NSCameraUsageDescription: 'call.md needs camera access to record video.', NSScreenCaptureUsageDescription: - 'Call.md needs screen capture access to record your screen.', + 'call.md needs screen capture access to record your screen.', }, }, dmg: { - title: 'Call.md ${version}${arch}', + title: 'call.md ${version}${arch}', icon: 'resources/icon.icns', window: { width: 540, diff --git a/install b/install new file mode 100644 index 0000000..6472497 --- /dev/null +++ b/install @@ -0,0 +1,128 @@ +#!/bin/bash +set -e + +# call.md Installer +# Usage: curl -fsSL https://artifacts.videodb.io/call.md/install | bash + +APP_NAME="call.md" +APP_DIR="/Applications/${APP_NAME}.app" +BASE_URL="https://artifacts.videodb.io/call.md" +VERSION="1.0.0" + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +BOLD='\033[1m' +NC='\033[0m' + +info() { printf "${BLUE}${BOLD}==>${NC} ${BOLD}%s${NC}\n" "$1"; } +success() { printf "${GREEN}${BOLD}==>${NC} ${BOLD}%s${NC}\n" "$1"; } +warn() { printf "${YELLOW}${BOLD}warning:${NC} %s\n" "$1"; } +error() { printf "${RED}${BOLD}error:${NC} %s\n" "$1" >&2; exit 1; } + +# --- Pre-flight checks --- + +if [ "$(uname)" != "Darwin" ]; then + error "This installer only supports macOS." +fi + +if ! command -v curl &>/dev/null; then + error "curl is required but not found." +fi + +# --- Detect architecture --- + +ARCH="$(uname -m)" +case "$ARCH" in + arm64) DMG_FILE="call.md-${VERSION}-arm64.dmg" ;; + x86_64) DMG_FILE="call.md-${VERSION}-x64.dmg" ;; + *) error "Unsupported architecture: $ARCH" ;; +esac + +DMG_URL="${BASE_URL}/${DMG_FILE}" + +echo "" +printf "${BOLD} call.md Installer${NC}\n" +echo " ─────────────────" +echo "" +info "Detected architecture: $ARCH" +info "Downloading ${DMG_FILE}..." + +# --- Download --- + +TMP_DIR="$(mktemp -d)" +TMP_DMG="${TMP_DIR}/${DMG_FILE}" + +cleanup() { + if [ -d "$TMP_DIR" ]; then + # Detach any mounted volume quietly + if [ -n "$MOUNT_POINT" ] && [ -d "$MOUNT_POINT" ]; then + hdiutil detach "$MOUNT_POINT" -quiet 2>/dev/null || true + fi + rm -rf "$TMP_DIR" + fi +} +trap cleanup EXIT + +curl -fSL --progress-bar "$DMG_URL" -o "$TMP_DMG" || error "Failed to download $DMG_URL" + +success "Download complete." + +# --- Mount DMG --- + +info "Mounting disk image..." +MOUNT_OUTPUT="$(hdiutil attach "$TMP_DMG" -nobrowse 2>&1)" +MOUNT_POINT="$(echo "$MOUNT_OUTPUT" | grep -o '/Volumes/.*' | head -1)" + +if [ -z "$MOUNT_POINT" ]; then + # Fallback: find mount point by listing volumes (case-insensitive) + MOUNT_POINT="$(find /Volumes -maxdepth 1 -iname "${APP_NAME}*" -type d 2>/dev/null | head -1)" +fi + +if [ -z "$MOUNT_POINT" ] || [ ! -d "$MOUNT_POINT" ]; then + error "Failed to mount disk image." +fi + +# --- Install --- + +SOURCE_APP="${MOUNT_POINT}/${APP_NAME}.app" +if [ ! -d "$SOURCE_APP" ]; then + # Try to find the .app in the volume + SOURCE_APP="$(find "$MOUNT_POINT" -maxdepth 1 -name "*.app" -type d | head -1)" +fi + +if [ -z "$SOURCE_APP" ] || [ ! -d "$SOURCE_APP" ]; then + error "Could not find ${APP_NAME}.app in the disk image." +fi + +if [ -d "$APP_DIR" ]; then + warn "Existing installation found. Replacing..." + rm -rf "$APP_DIR" +fi + +info "Installing to /Applications..." +cp -R "$SOURCE_APP" "$APP_DIR" || error "Failed to copy app to /Applications. You may need to run with sudo." + +# --- Remove quarantine --- + +info "Removing quarantine attribute..." +xattr -cr "$APP_DIR" 2>/dev/null || true + +# --- Cleanup --- + +info "Cleaning up..." +hdiutil detach "$MOUNT_POINT" -quiet 2>/dev/null || true +MOUNT_POINT="" + +# --- Done --- + +echo "" +success "call.md has been installed to /Applications!" +echo "" +echo " Next steps:" +echo " 1. Open call.md from Applications or Spotlight" +echo " 2. Grant Microphone and Screen Recording permissions when prompted" +echo " 3. Enter your VideoDB API key (get one at https://console.videodb.io)" +echo "" diff --git a/package-lock.json b/package-lock.json index fecef29..fe6a322 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "@videodb/recorder": "^0.2.4", "better-sqlite3": "^12.6.2", "drizzle-orm": "^0.44.1", - "fix-path": "^5.0.0", + "fix-path": "^4.0.0", "hono": "^4.7.5", "openai": "^6.19.0", "pino": "^9.6.0", @@ -6419,48 +6419,20 @@ } }, "node_modules/fix-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/fix-path/-/fix-path-5.0.0.tgz", - "integrity": "sha512-erEWGGCN7RIu1bXTCfNVpVBdm0f5mwcbeja+4QXiEZzIQukP401sbpu8gd3Ny1vS34YNeswyMO0TdT2tP5OlHA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fix-path/-/fix-path-4.0.0.tgz", + "integrity": "sha512-g31GX207Tt+psI53ZSaB1egprYbEN0ZYl90aKcO22A2LmCNnFsSq3b5YpoKp3E/QEiWByTXGJOkFQG4S07Bc1A==", "license": "MIT", "dependencies": { - "shell-path": "^3.1.0", - "strip-ansi": "^7.1.2" + "shell-path": "^3.0.0" }, "engines": { - "node": ">=20" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fix-path/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/fix-path/node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/follow-redirects": { "version": "1.15.11", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", diff --git a/package.json b/package.json index c8e7c73..5b4734d 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@videodb/recorder": "^0.2.4", "better-sqlite3": "^12.6.2", "drizzle-orm": "^0.44.1", - "fix-path": "^5.0.0", + "fix-path": "^4.0.0", "hono": "^4.7.5", "openai": "^6.19.0", "pino": "^9.6.0",