Build custom WordPress plugins with AI. No coding required - just describe what you need.
+
+
+
+
+
+
+
+
Chat to Build
+
Describe your plugin in plain English. Our AI understands WordPress and creates working code.
+
+
+
+
+
+
+
+
Quick Start Ideas
+
Tap a suggestion to get started:
+
+
+
Contact Form Plugin
+
Spam protection & email notifications
+
+
+
Testimonial Slider
+
Admin management & shortcodes
+
+
+
SEO Meta Tags
+
Social media preview support
+
+
+
+
+
+
+
+
+
+
You're All Set!
+
Start building your first plugin. You can always ask questions or get help along the way.
+
+
+
+
+
+
+
+
+
+
Plugin Compass
+
+
+
+
+
Ready to Build!
+
What would you like to create today?
+
+
+
+
+
+
+
+
New Plugin
+
Start building from scratch
+
+
+
+
+
+
+
+
My Plugins
+
View your saved plugins
+
+
+
+
+
+
+
+
Templates
+
Start from a template
+
+
+
+
+
+
+
+
+`;
+
+ await fs.writeFile(path.join(dest, 'index.html'), mobileIndex, 'utf8');
+}
+
async function main() {
await copyUi();
- await injectBridge();
+ await injectMetaTags();
+ await createMobileIndex();
console.log(`UI prepared in ${dest}`);
}
diff --git a/windows-app/README.md b/windows-app/README.md
index 944c484..f5c0b9c 100644
--- a/windows-app/README.md
+++ b/windows-app/README.md
@@ -1,44 +1,54 @@
-# Windows Desktop App
-
-This folder contains the Windows desktop build for the project. The desktop app reuses the existing web UI (apps and builder screens) and wraps it with a native shell that can run OpenCode locally, save output on the user's machine, and sync finished apps to the backend.
-
-## Goals
-- Reuse the existing web UI with minimal divergence.
-- Keep memory footprint low (Tauri + WebView2, no Electron).
-- Run OpenCode locally with API keys pulled securely from the backend; users never see the raw key.
-- Persist work on the user's device and sync results back to the backend so apps are also available on the website.
-- Ship a single Windows `.exe` via GitHub Actions; do not build locally.
-
-## How it works
-- **UI reuse:** `npm run prepare-ui` copies `../chat/public` into `ui-dist` and injects a lightweight bridge script so existing pages can talk to the Tauri commands.
-- **Native shell:** Tauri hosts the UI from `ui-dist` and exposes a few commands (`save_api_key`, `persist_app`, `list_apps`, `sync_app`, `run_opencode_task`).
-- **Local storage:** Apps are saved under the OS app data directory, isolated per user. API keys are written to an on-disk Tauri store (no read command is exposed back to JS).
-- **OpenCode execution:** `run_opencode_task` shells out to a local OpenCode binary stored under the app data folder and injects the API key into the process environment. If the binary is missing, the command returns a clear error so the UI can download or prompt the user.
-- **Syncing:** `sync_app` posts the locally saved app JSON to the backend (configured via the `BACKEND_BASE_URL` env var in CI or a `.env` file). After a successful sync, the app is reachable from the website.
-- **Key handling:** Only the backend may return API keys; the UI can request that the native layer saves the key, but there is no command to read it back, preventing direct OpenCode access from the web runtime.
-
-## Setup
-1. Install prerequisites (Rust stable, Node 18+, WebView2 runtime on Windows).
-2. From the repo root: `cd "windows app"`.
-3. Install dependencies: `npm install` (no build here).
-4. Pull UI assets: `npm run prepare-ui`.
-5. (Optional) Create `.env` in this folder with `BACKEND_BASE_URL=https://your-backend.example/api`.
-
-## Development
-- `npm run dev` starts Tauri using the copied UI in `ui-dist`. The bridge script is auto-injected into HTML files when preparing the UI.
-- Commands are exposed via `window.windowsAppBridge` (see `tauri-bridge.js`). Existing pages can call these helpers without changing core logic.
-
-## CI build (single Windows exe)
-- GitHub Actions workflow: `.github/workflows/windows-app.yml`.
-- The action runs on `windows-latest`, installs Rust and Node, prepares the UI, and runs `npm run build` to produce the bundled `.exe` (plus installer artifacts). Artifacts are uploaded for download; no local build is performed here.
-
-## Security notes
-- No command exposes the stored API key to the web layer.
-- OpenCode is only invoked from the Rust side with the key set via environment variables.
-- File system allowlist in Tauri is restricted to the app data directory plus the bundled UI folder.
-- If additional secrets are needed, source them from the backend and save via `save_api_key` only.
-
-## Next steps
-- Wire the existing apps and builder pages to call `window.windowsAppBridge` where persistence or syncing is needed.
-- Add OpenCode binary download/install flow in the UI using `run_opencode_task` error responses to detect missing binaries.
-- Point `BACKEND_BASE_URL` to the real API endpoint in CI and secrets for production builds.
+# Plugin Compass Desktop (Electron)
+
+This folder contains the desktop app build for Plugin Compass. The desktop app reuses the existing web UI and wraps it with a native Electron shell that can run OpenCode locally, save output on the user's machine, and sync finished plugins to the backend.
+
+## Features
+- Reuses the existing web UI with minimal divergence.
+- Self-updating via electron-updater (no manual downloads required).
+- Run OpenCode locally with API keys pulled securely from the backend.
+- Persist work on the user's device and sync results back to the backend.
+- Build via GitHub Actions.
+
+## Self-Update System
+
+The app includes an automatic update system using `electron-updater`:
+
+1. **Automatic Check**: On startup, the app checks for updates from GitHub Releases.
+2. **Background Download**: Updates download in the background without interrupting the user.
+3. **User Notification**: When an update is ready, the user is notified via the UI.
+4. **One-Click Install**: User can restart the app to apply the update.
+
+### How Updates Work
+- Updates are published to GitHub Releases by the CI workflow.
+- `electron-updater` downloads the new version from GitHub.
+- The update is verified before installation.
+- Users can choose when to restart and apply the update.
+
+### Developer Notes
+- Updates require code-signing for production (not needed for testing).
+- The update server is GitHub Releases (configured in package.json).
+- Update events are exposed via `window.windowsAppBridge`:
+ - `checkForUpdates()` - Manually check for updates
+ - `downloadUpdate()` - Download available update
+ - `installUpdate()` - Restart and install
+ - `onUpdateAvailable(callback)` - Listen for update available
+ - `onUpdateDownloaded(callback)` - Listen for update ready
+ - `onDownloadProgress(callback)` - Track download progress
+
+## Setup
+1. Install prerequisites (Node 18+).
+2. From this folder: `npm install`.
+3. Pull UI assets: `npm run prepare-ui`.
+
+## Development
+- `npm run dev` starts Electron using the copied UI in `ui-dist`.
+- Commands are exposed via `window.windowsAppBridge`.
+
+## CI build
+- GitHub Actions workflow: `.github/workflows/build-electron-app.yml`.
+- The action runs on `windows-latest`, builds the app, and publishes to GitHub Releases.
+
+## Security notes
+- No command exposes the stored API key to the web layer.
+- OpenCode is only invoked from the main process with the key set via environment variables.
+- File system access is restricted to the app data directory.
diff --git a/windows-app/electron-main.js b/windows-app/electron-main.js
index 31e034e..b8f4b2a 100644
--- a/windows-app/electron-main.js
+++ b/windows-app/electron-main.js
@@ -1,4 +1,5 @@
const { app, BrowserWindow, ipcMain } = require('electron');
+const { autoUpdater } = require('electron-updater');
const path = require('path');
const fs = require('fs');
const https = require('https');
@@ -65,7 +66,7 @@ function createWindow() {
contextIsolation: true,
nodeIntegration: false,
},
- title: 'ShopifyAI Desktop',
+ title: 'Plugin Compass',
show: false,
});
@@ -81,10 +82,16 @@ function createWindow() {
} else {
mainWindow.loadURL('http://localhost:3000');
}
+
+ mainWindow.webContents.on('did-finish-load', () => {
+ mainWindow.webContents.send('app-version', app.getVersion());
+ });
}
app.whenReady().then(() => {
createWindow();
+
+ autoUpdater.checkForUpdatesAndNotify();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
@@ -99,6 +106,64 @@ app.on('window-all-closed', () => {
}
});
+autoUpdater.on('update-available', () => {
+ if (mainWindow) {
+ mainWindow.webContents.send('update-available');
+ }
+});
+
+autoUpdater.on('update-downloaded', () => {
+ if (mainWindow) {
+ mainWindow.webContents.send('update-downloaded');
+ }
+});
+
+autoUpdater.on('error', (err) => {
+ if (mainWindow) {
+ mainWindow.webContents.send('update-error', err.message);
+ }
+});
+
+autoUpdater.on('download-progress', (progressObj) => {
+ if (mainWindow) {
+ mainWindow.webContents.send('download-progress', {
+ percent: progressObj.percent,
+ transferred: progressObj.transferred,
+ total: progressObj.total,
+ });
+ }
+});
+
+ipcMain.handle('check-for-updates', async () => {
+ try {
+ const result = await autoUpdater.checkForUpdates();
+ return {
+ available: result && result.updateInfo && result.updateInfo.version !== app.getVersion(),
+ currentVersion: app.getVersion(),
+ latestVersion: result ? result.updateInfo.version : app.getVersion(),
+ };
+ } catch (err) {
+ return { error: err.message };
+ }
+});
+
+ipcMain.handle('download-update', async () => {
+ try {
+ await autoUpdater.downloadUpdate();
+ return { success: true };
+ } catch (err) {
+ return { error: err.message };
+ }
+});
+
+ipcMain.handle('install-update', () => {
+ autoUpdater.quitAndInstall();
+});
+
+ipcMain.handle('get-version', () => {
+ return app.getVersion();
+});
+
ipcMain.handle('save-api-key', async (event, token) => {
if (!token || typeof token !== 'string' || token.trim() === '') {
throw new Error('token is required');
diff --git a/windows-app/electron-preload.js b/windows-app/electron-preload.js
index 3c721f8..0662f19 100644
--- a/windows-app/electron-preload.js
+++ b/windows-app/electron-preload.js
@@ -7,4 +7,25 @@ contextBridge.exposeInMainWorld('windowsAppBridge', {
syncApp: (appId) => ipcRenderer.invoke('sync-app', appId),
runOpencodeTask: (appId, taskName, args) =>
ipcRenderer.invoke('run-opencode-task', appId, taskName, args || []),
+
+ getVersion: () => ipcRenderer.invoke('get-version'),
+ checkForUpdates: () => ipcRenderer.invoke('check-for-updates'),
+ downloadUpdate: () => ipcRenderer.invoke('download-update'),
+ installUpdate: () => ipcRenderer.invoke('install-update'),
+
+ onUpdateAvailable: (callback) => {
+ ipcRenderer.on('update-available', () => callback());
+ },
+ onUpdateDownloaded: (callback) => {
+ ipcRenderer.on('update-downloaded', () => callback());
+ },
+ onUpdateError: (callback) => {
+ ipcRenderer.on('update-error', (event, error) => callback(error));
+ },
+ onDownloadProgress: (callback) => {
+ ipcRenderer.on('download-progress', (event, progress) => callback(progress));
+ },
+ onAppVersion: (callback) => {
+ ipcRenderer.on('app-version', (event, version) => callback(version));
+ },
});
diff --git a/windows-app/package.json b/windows-app/package.json
index a4e7400..32ad0e5 100644
--- a/windows-app/package.json
+++ b/windows-app/package.json
@@ -1,5 +1,5 @@
{
- "name": "shopify-ai-windows-app",
+ "name": "plugin-compass-desktop",
"version": "0.1.0",
"private": true,
"main": "electron-main.js",
@@ -9,17 +9,20 @@
"build": "npm run prepare-ui && electron-builder",
"build:win": "npm run prepare-ui && electron-builder --win",
"build:mac": "npm run prepare-ui && electron-builder --mac",
- "build:linux": "npm run prepare-ui && electron-builder --linux"
+ "build:linux": "npm run prepare-ui && electron-builder --linux",
+ "postinstall": "electron-builder install-app-deps"
+ },
+ "dependencies": {
+ "electron-updater": "^6.1.7"
},
- "dependencies": {},
"devDependencies": {
"electron": "^28.0.0",
"electron-builder": "^24.9.1",
"fs-extra": "^11.2.0"
},
"build": {
- "appId": "com.shopifyai.desktop",
- "productName": "ShopifyAI Desktop",
+ "appId": "com.plugincompass.desktop",
+ "productName": "Plugin Compass",
"directories": {
"output": "dist"
},
@@ -30,22 +33,38 @@
],
"win": {
"target": [
- "nsis",
- "portable"
+ "nsis"
],
- "icon": "assets/icon.ico"
+ "icon": "assets/icon.ico",
+ "publish": {
+ "provider": "github",
+ "owner": "southseact-3d",
+ "repo": "shopify-ai-backup"
+ }
},
"mac": {
"target": "dmg",
- "icon": "assets/icon.icns"
+ "icon": "assets/icon.icns",
+ "publish": {
+ "provider": "github",
+ "owner": "southseact-3d",
+ "repo": "shopify-ai-backup"
+ }
},
"linux": {
"target": "AppImage",
- "icon": "assets/icon.png"
+ "icon": "assets/icon.png",
+ "publish": {
+ "provider": "github",
+ "owner": "southseact-3d",
+ "repo": "shopify-ai-backup"
+ }
},
"nsis": {
"oneClick": false,
- "allowToChangeInstallationDirectory": true
+ "allowToChangeInstallationDirectory": true,
+ "createDesktopShortcut": true,
+ "createStartMenuShortcut": true
}
}
}