Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ build/ts/
.claude/
CLAUDE.md
TYPESCRIPT_MIGRATION.md
Makefile
# ai-dev-kit MCP writes these into its working directory (Mason repo root when
# spawned from Mason). They're per-machine resource ledgers — never commit.
.databricks-resources.json
Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "1.3.12"
".": "1.3.13"
}
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,32 @@ curl -fsSL https://raw.githubusercontent.com/databricks-solutions/mason/main/scr

Download `Mason-*-arm64.dmg` from [the latest release](https://github.com/databricks-solutions/mason/releases/latest), open it, and drag Mason to Applications.

### Other platforms
### Windows (x64 or ARM64) — one-line install

Windows and Linux builds are not yet published. The `electron-builder` config supports them — building from source on those platforms (`npm ci && npm run build:win` / `npm run build:linux`) will produce installers.
Open PowerShell and run:

```powershell
irm https://raw.githubusercontent.com/databricks-solutions/mason/main/scripts/install.ps1 | iex
```

This auto-detects your architecture (x64 vs ARM64), downloads the matching installer from GitHub Releases, and runs it silently as a per-user install (no admin elevation). Mason launches automatically when it finishes. Pin to a specific version:

```powershell
$env:MASON_VERSION = "v1.3.13"; irm https://raw.githubusercontent.com/databricks-solutions/mason/main/scripts/install.ps1 | iex
```

### Windows — manual install

Download the matching `.exe` from [the latest release](https://github.com/databricks-solutions/mason/releases/latest) and run it:

- `Mason Setup X.Y.Z.exe` — x64 (Intel / AMD)
- `Mason Setup X.Y.Z-arm64.exe` — ARM64 (Surface Pro X, Copilot+ PCs)

Not sure which architecture you have? Settings → System → About → "System type".

### Linux

Linux builds aren't published yet. Build from source: `npm ci && npm run build:linux` produces an `.AppImage`.

## How to get help

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mason",
"version": "1.3.12",
"version": "1.3.13",
"description": "Desktop chat app for Databricks AI Gateway with MCP tool calling",
"author": "Databricks",
"main": "build/ts/main.js",
Expand Down Expand Up @@ -72,7 +72,13 @@
},
"win": {
"target": [
"nsis"
{
"target": "nsis",
"arch": [
"x64",
"arm64"
]
}
],
"icon": "build/icon_square.png"
},
Expand Down
90 changes: 90 additions & 0 deletions scripts/install.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Mason installer for Windows. Usage:
#
# irm https://raw.githubusercontent.com/databricks-solutions/mason/main/scripts/install.ps1 | iex
#
# Pin to a specific version:
#
# $env:MASON_VERSION = "v1.3.13"; irm https://raw.githubusercontent.com/databricks-solutions/mason/main/scripts/install.ps1 | iex
#
# Downloads the latest Mason release for the current architecture (x64 or
# ARM64) and runs the NSIS installer in silent mode. Per-user install —
# no admin elevation required.

$ErrorActionPreference = "Stop"
$repo = "databricks-solutions/mason"

# --- Detect architecture ---
$arch = $env:PROCESSOR_ARCHITECTURE
if ($arch -eq "ARM64") {
$suffix = "-arm64"
$archLabel = "ARM64"
} elseif ($arch -eq "AMD64" -or $arch -eq "x86_64") {
$suffix = ""
$archLabel = "x64"
} else {
Write-Host "[mason] Unsupported architecture: $arch (Mason supports x64 and ARM64)" -ForegroundColor Red
exit 1
}

# --- Look up release ---
$tag = $env:MASON_VERSION
if ($tag) {
Write-Host "[mason] Looking up release $tag for $archLabel..."
$releaseUrl = "https://api.github.com/repos/$repo/releases/tags/$tag"
} else {
Write-Host "[mason] Looking up latest release for $archLabel..."
$releaseUrl = "https://api.github.com/repos/$repo/releases/latest"
}

try {
$release = Invoke-RestMethod -Uri $releaseUrl -Headers @{
"User-Agent" = "mason-installer"
"Accept" = "application/vnd.github+json"
}
} catch {
Write-Host "[mason] Failed to query GitHub release: $_" -ForegroundColor Red
exit 1
}

$version = $release.tag_name -replace "^v",""
$assetName = "Mason Setup $version$suffix.exe"
$asset = $release.assets | Where-Object { $_.name -eq $assetName }
if (-not $asset) {
Write-Host "[mason] No release asset matching '$assetName' (architecture $archLabel)" -ForegroundColor Red
Write-Host "[mason] Available assets:"
$release.assets | ForEach-Object { Write-Host " - $($_.name)" }
exit 1
}

# --- Download ---
$tmp = Join-Path $env:TEMP $assetName
Write-Host "[mason] Downloading $assetName ($([math]::Round($asset.size / 1MB, 1)) MB)..."
try {
Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $tmp -UseBasicParsing
} catch {
Write-Host "[mason] Download failed: $_" -ForegroundColor Red
exit 1
}

# --- Install ---
Write-Host "[mason] Running installer (per-user, no admin required)..."
# /S = silent install. electron-builder NSIS default install path is
# %LOCALAPPDATA%\Programs\mason\Mason.exe and the installer adds a
# Start-Menu shortcut + Desktop shortcut automatically.
$proc = Start-Process -FilePath $tmp -ArgumentList "/S" -PassThru -Wait
if ($proc.ExitCode -ne 0) {
Write-Host "[mason] Installer exited with code $($proc.ExitCode)" -ForegroundColor Red
Remove-Item $tmp -ErrorAction SilentlyContinue
exit 1
}

$installPath = Join-Path $env:LOCALAPPDATA "Programs\mason\Mason.exe"
Remove-Item $tmp -ErrorAction SilentlyContinue

if (Test-Path $installPath) {
Write-Host "[mason] Installed at $installPath" -ForegroundColor Green
Write-Host "[mason] Launching..."
Start-Process $installPath
} else {
Write-Host "[mason] Install completed. Launch Mason from the Start Menu." -ForegroundColor Green
}
25 changes: 23 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1308,8 +1308,23 @@ const IMAGE_MIME: Record<string, string> = {
gif: "image/gif",
webp: "image/webp",
};
// @ts-ignore — pdf-parse has no @types
const { PDFParse } = require("pdf-parse");
// pdf-parse is loaded lazily inside the PDF branch below. Eager require fails
// on Windows because the bundled pdf.js calls DOMMatrix during module init,
// which doesn't exist in Electron's main-process Node context on Windows.
// Lazy-loading keeps startup clean; PDF uploads on platforms where the load
// fails return a friendly error instead of crashing the whole app.
let _PDFParse: any = undefined;
function loadPDFParse(): any {
if (_PDFParse !== undefined) return _PDFParse;
try {
// @ts-ignore — pdf-parse has no @types
_PDFParse = require("pdf-parse").PDFParse;
} catch (err) {
console.error("[UPLOAD] pdf-parse failed to load:", (err as Error).message);
_PDFParse = null;
}
return _PDFParse;
}

ipcMain.handle("read-file-for-upload", async (_event: IpcMainInvokeEvent, { filePath }: { filePath: string }) => {
if (!fs.existsSync(filePath)) throw new Error(`File not found: ${filePath}`);
Expand All @@ -1335,6 +1350,12 @@ ipcMain.handle("read-file-for-upload", async (_event: IpcMainInvokeEvent, { file
throw new Error(
`PDF too large (${(stats.size / 1024 / 1024).toFixed(1)} MB > ${MAX_PDF_BYTES / 1024 / 1024} MB)`
);
const PDFParse = loadPDFParse();
if (!PDFParse) {
throw new Error(
"PDF support isn't available on this build. Convert the PDF to text or paste its content directly into the chat."
);
}
const buf = fs.readFileSync(filePath);
const parser = new PDFParse({ data: buf });
let result: any;
Expand Down
Loading