From cf6adeff83b9e0c6c2c6942e5a23481d9a6aa887 Mon Sep 17 00:00:00 2001 From: Rahul <53112598+rahulraonatarajan@users.noreply.github.com> Date: Tue, 24 Mar 2026 17:39:31 -0700 Subject: [PATCH 1/4] feat: single-click Windows installer (download button instead of terminal command) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Windows users now get a "Download Installer" button identical to Mac, instead of having to copy-paste a PowerShell command into a terminal. The .bat file is already double-click ready — no admin rights needed. Made-with: Cursor --- .../src/onboarding/onboarding.ts | 27 +++++++++++++++++++ .../src/onboarding/onboarding.ts | 27 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/apps/extension-chrome/src/onboarding/onboarding.ts b/apps/extension-chrome/src/onboarding/onboarding.ts index 21736c8..db1a9dc 100644 --- a/apps/extension-chrome/src/onboarding/onboarding.ts +++ b/apps/extension-chrome/src/onboarding/onboarding.ts @@ -435,6 +435,8 @@ const HELPER_INSTALL_BASE = 'https://raw.githubusercontent.com/joelnishanth/offlyn-apply/main/scripts/native-host'; const HELPER_PKG_URL = 'https://github.com/joelnishanth/offlyn-apply/releases/download/v0.5.0/offlyn-helper.pkg'; +const HELPER_WIN_BAT_URL = + 'https://github.com/joelnishanth/offlyn-apply/releases/download/v0.5.0/offlyn-helper-install.bat'; function detectOS(): 'mac' | 'windows' | 'linux' { const ua = navigator.userAgent.toLowerCase(); @@ -477,6 +479,17 @@ function populateHelperInstructions(): void { Download Installer `; + } else if (os === 'windows') { + container.innerHTML = ` +
Download and double-click the installer — it takes about 10 seconds. No terminal required.
+ + ${DOWNLOAD_SVG} + Download Installer + + `; } else { const cmd = getHelperInstallCommand(); const hint = getHelperTerminalHint(); @@ -610,6 +623,20 @@ function setupOllamaStepListeners(): void {After the installer finishes, click Re-test Connection below.
`; + } else if (os === 'windows') { + corsWrap.innerHTML = ` ++ To fix CORS automatically, install the Offlyn Helper first — it configures Ollama permissions in one step. +
+ + ${DOWNLOAD_SVG} + Download Installer + +After the installer finishes, click Re-test Connection below.
+ `; } else { const cmd = getHelperInstallCommand(); const hint = getHelperTerminalHint(); diff --git a/apps/extension-firefox/src/onboarding/onboarding.ts b/apps/extension-firefox/src/onboarding/onboarding.ts index bae1731..f443fa3 100644 --- a/apps/extension-firefox/src/onboarding/onboarding.ts +++ b/apps/extension-firefox/src/onboarding/onboarding.ts @@ -433,6 +433,8 @@ const HELPER_INSTALL_BASE = 'https://raw.githubusercontent.com/joelnishanth/offlyn-apply/main/scripts/native-host'; const HELPER_PKG_URL = 'https://github.com/joelnishanth/offlyn-apply/releases/download/v0.5.0/offlyn-helper.pkg'; +const HELPER_WIN_BAT_URL = + 'https://github.com/joelnishanth/offlyn-apply/releases/download/v0.5.0/offlyn-helper-install.bat'; function detectOS(): 'mac' | 'windows' | 'linux' { const ua = navigator.userAgent.toLowerCase(); @@ -475,6 +477,17 @@ function populateHelperInstructions(): void { Download Installer `; + } else if (os === 'windows') { + container.innerHTML = ` +Download and double-click the installer — it takes about 10 seconds. No terminal required.
+ + ${DOWNLOAD_SVG} + Download Installer + + `; } else { const cmd = getHelperInstallCommand(); const hint = getHelperTerminalHint(); @@ -607,6 +620,20 @@ function setupOllamaStepListeners(): void {After the installer finishes, click Re-test Connection below.
`; + } else if (os === 'windows') { + corsWrap.innerHTML = ` ++ To fix CORS automatically, install the Offlyn Helper first — it configures Ollama permissions in one step. +
+ + ${DOWNLOAD_SVG} + Download Installer + +After the installer finishes, click Re-test Connection below.
+ `; } else { const cmd = getHelperInstallCommand(); const hint = getHelperTerminalHint(); From f16d45c196212986b48032e4cc644e71bc03d05c Mon Sep 17 00:00:00 2001 From: Rahul <53112598+rahulraonatarajan@users.noreply.github.com> Date: Tue, 24 Mar 2026 21:42:04 -0700 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20Windows=20native=20messaging=20host?= =?UTF-8?q?=20=E2=80=94=20.bat=20wrapper,=20JSON=20escaping,=20local=20set?= =?UTF-8?q?up=20script?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create helper.bat wrapper so Chrome/Firefox can launch the PS1 host (native messaging cannot execute .ps1 files directly) - Use forward slashes in manifest JSON path to avoid invalid escape sequences - Download setup-win.ps1 locally for offline reliability - host.ps1 now prefers local setup-win.ps1 if present (matching host.py) - Point download URLs at feature branch for testing Made-with: Cursor --- scripts/native-host/host.ps1 | 16 ++++++++++++---- scripts/native-host/install-win.bat | 23 +++++++++++++++++++---- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/scripts/native-host/host.ps1 b/scripts/native-host/host.ps1 index e57ad76..abe00c9 100644 --- a/scripts/native-host/host.ps1 +++ b/scripts/native-host/host.ps1 @@ -32,13 +32,21 @@ function Send-NativeMessage($obj) { } function Invoke-Setup { - $url = "$SCRIPT_BASE/setup-win.ps1" + $offlyn_dir = Join-Path $env:USERPROFILE ".offlyn" + $local_script = Join-Path $offlyn_dir "setup-win.ps1" $logFile = "$env:TEMP\offlyn-setup-$(Get-Date -Format 'yyyyMMddHHmmss').log" try { - $process = Start-Process powershell.exe ` - -ArgumentList "-ExecutionPolicy", "Bypass", "-Command", "irm '$url' | iex" ` - -Wait -PassThru -RedirectStandardOutput $logFile -RedirectStandardError $logFile + if (Test-Path $local_script) { + $process = Start-Process powershell.exe ` + -ArgumentList "-ExecutionPolicy", "Bypass", "-File", $local_script ` + -Wait -PassThru -RedirectStandardOutput $logFile -RedirectStandardError $logFile + } else { + $url = "$SCRIPT_BASE/setup-win.ps1" + $process = Start-Process powershell.exe ` + -ArgumentList "-ExecutionPolicy", "Bypass", "-Command", "irm '$url' | iex" ` + -Wait -PassThru -RedirectStandardOutput $logFile -RedirectStandardError $logFile + } $output = if (Test-Path $logFile) { Get-Content $logFile -Raw } else { "" } Remove-Item $logFile -Force -ErrorAction SilentlyContinue diff --git a/scripts/native-host/install-win.bat b/scripts/native-host/install-win.bat index 12c94b9..7a77327 100644 --- a/scripts/native-host/install-win.bat +++ b/scripts/native-host/install-win.bat @@ -8,8 +8,10 @@ setlocal EnableDelayedExpansion set HOST_NAME=ai.offlyn.helper set OFFLYN_DIR=%USERPROFILE%\.offlyn -set HOST_SCRIPT=%OFFLYN_DIR%\helper.ps1 -set RAW_BASE=https://raw.githubusercontent.com/joelnishanth/offlyn-apply/main/scripts/native-host +set HOST_PS1=%OFFLYN_DIR%\helper.ps1 +set HOST_BAT=%OFFLYN_DIR%\helper.bat +set RAW_BASE=https://raw.githubusercontent.com/rahulraonatarajan/offlyn-apply/Windows-ollama-setup/scripts/native-host +set SETUP_BASE=https://raw.githubusercontent.com/rahulraonatarajan/offlyn-apply/Windows-ollama-setup/scripts/setup-ollama set CHROME_EXT_ID=bjllpojjllhfghiemokcoknfmhpmfbph set FIREFOX_EXT_ID={e0857c2d-15a6-4d0c-935e-57761715dc3d} @@ -22,7 +24,7 @@ if not exist "%OFFLYN_DIR%" mkdir "%OFFLYN_DIR%" :: Download the PowerShell host script powershell -ExecutionPolicy Bypass -Command ^ - "Invoke-WebRequest -Uri '%RAW_BASE%/host.ps1' -OutFile '%HOST_SCRIPT%' -UseBasicParsing" + "Invoke-WebRequest -Uri '%RAW_BASE%/host.ps1' -OutFile '%HOST_PS1%' -UseBasicParsing" if %errorlevel% neq 0 ( echo ERROR: Failed to download helper script. echo Please check your internet connection and try again. @@ -30,13 +32,26 @@ if %errorlevel% neq 0 ( exit /b 1 ) +:: Download setup-win.ps1 locally so host.ps1 can run it without re-downloading +powershell -ExecutionPolicy Bypass -Command ^ + "Invoke-WebRequest -Uri '%SETUP_BASE%/setup-win.ps1' -OutFile '%OFFLYN_DIR%\setup-win.ps1' -UseBasicParsing" + +:: Create the .bat wrapper — Chrome/Firefox cannot launch .ps1 directly +( + echo @echo off + echo powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File "%%~dp0helper.ps1" %%* +) > "%HOST_BAT%" + +:: Build a JSON-safe path (forward slashes avoid invalid JSON escape sequences) +set MANIFEST_PATH=%HOST_BAT:\=/% + :: Write the manifest JSON set MANIFEST_FILE=%OFFLYN_DIR%\%HOST_NAME%.json ( echo { echo "name": "%HOST_NAME%", echo "description": "Offlyn AI Setup Helper", - echo "path": "%HOST_SCRIPT%", + echo "path": "%MANIFEST_PATH%", echo "type": "stdio", echo "allowed_origins": ["chrome-extension://%CHROME_EXT_ID%/"], echo "allowed_extensions": ["%FIREFOX_EXT_ID%"] From ed30d41fefaf8791469357aa0e7f6b5bf83cc192 Mon Sep 17 00:00:00 2001 From: Rahul <53112598+rahulraonatarajan@users.noreply.github.com> Date: Tue, 24 Mar 2026 21:47:55 -0700 Subject: [PATCH 3/4] fix: align host.ps1 fallback URL with install-win.bat branch Made-with: Cursor --- scripts/native-host/host.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/native-host/host.ps1 b/scripts/native-host/host.ps1 index abe00c9..76a391b 100644 --- a/scripts/native-host/host.ps1 +++ b/scripts/native-host/host.ps1 @@ -7,7 +7,7 @@ # { "cmd": "run_setup" } -> { "type": "done", "ok": true/false, "output": "..." } $VERSION = "1.0.0" -$SCRIPT_BASE = "https://raw.githubusercontent.com/joelnishanth/offlyn-apply/main/scripts/setup-ollama" +$SCRIPT_BASE = "https://raw.githubusercontent.com/rahulraonatarajan/offlyn-apply/Windows-ollama-setup/scripts/setup-ollama" function Read-NativeMessage { $stdin = [Console]::OpenStandardInput() From a1af98fbc97db28d5ae98010347d85281742ab24 Mon Sep 17 00:00:00 2001 From: Rahul NOfflyn uses on-device AI — your data never leaves your computer.
-We believe AI should work for you privately. Offlyn runs AI models directly on your device so your resume, work history, and personal info stay 100% yours.
+We believe AI should work for you privately. Offlyn runs AI models directly on your device so your resume, work history, and personal info stay 100% yours. Once downloaded, the model runs fully offline — no data is ever sent to a server and there is no per-query cost.
After the installer finishes, click Re-test Connection below.
`; @@ -633,7 +642,7 @@ function setupOllamaStepListeners(): void { class="btn btn-primary" style="display:inline-flex;align-items:center;gap:8px;font-size:13px;padding:9px 16px;text-decoration:none;margin-bottom:10px;"> ${DOWNLOAD_SVG} - Download Installer + Download for Windows (.bat)After the installer finishes, click Re-test Connection below.
`; diff --git a/apps/extension-chrome/src/shared/error-classify.ts b/apps/extension-chrome/src/shared/error-classify.ts index ee21dfb..d955555 100644 --- a/apps/extension-chrome/src/shared/error-classify.ts +++ b/apps/extension-chrome/src/shared/error-classify.ts @@ -31,8 +31,8 @@ export function enrichParseErrorMessage(raw: string): string { if (/not found|404|model .* not found/i.test(raw)) { return ( 'Required AI model not found. Please install the models by running:\n' + - 'ollama pull llama3.2\n' + - 'ollama pull nomic-embed-text' + 'ollama pull llama3.2:1b\n' + + 'ollama pull nomic-embed-text' ); } return raw; diff --git a/apps/extension-chrome/src/shared/mastra-agent.ts b/apps/extension-chrome/src/shared/mastra-agent.ts index 946d292..14862cc 100644 --- a/apps/extension-chrome/src/shared/mastra-agent.ts +++ b/apps/extension-chrome/src/shared/mastra-agent.ts @@ -4,8 +4,6 @@ */ import browser from './browser-compat'; -import { generateText } from 'ai'; -import { ollama } from 'ollama-ai-provider-v2'; import type { Message } from './types'; /** @@ -41,19 +39,45 @@ class MastraAgentService { private baseUrl: string; private model: string; private embeddingModel: string; - private ollamaProvider: ReturnTypeOfflyn uses on-device AI — your data never leaves your computer.
-We believe AI should work for you privately. Offlyn runs AI models directly on your device so your resume, work history, and personal info stay 100% yours.
+We believe AI should work for you privately. Offlyn runs AI models directly on your device so your resume, work history, and personal info stay 100% yours. Once downloaded, the model runs fully offline — no data is ever sent to a server and there is no per-query cost.
After the installer finishes, click Re-test Connection below.
`; @@ -630,7 +630,7 @@ function setupOllamaStepListeners(): void { class="btn btn-primary" style="display:inline-flex;align-items:center;gap:8px;font-size:13px;padding:9px 16px;text-decoration:none;margin-bottom:10px;"> ${DOWNLOAD_SVG} - Download Installer + Download for Windows (.bat)After the installer finishes, click Re-test Connection below.
`; diff --git a/apps/extension-firefox/src/shared/mastra-agent.ts b/apps/extension-firefox/src/shared/mastra-agent.ts index f9fb3d1..8d05566 100644 --- a/apps/extension-firefox/src/shared/mastra-agent.ts +++ b/apps/extension-firefox/src/shared/mastra-agent.ts @@ -3,8 +3,6 @@ * Browser-compatible implementation using ollama-ai-provider-v2 */ -import { generateText } from 'ai'; -import { ollama } from 'ollama-ai-provider-v2'; import type { Message } from './types'; // Browser API shim for environments that don't have it @@ -36,19 +34,45 @@ class MastraAgentService { private baseUrl: string; private model: string; private embeddingModel: string; - private ollamaProvider: ReturnType