From 24c79defff4c528b14d02343bf4a3c76ef5fa8ce Mon Sep 17 00:00:00 2001 From: Kunthawat Greethong Date: Fri, 19 Dec 2025 09:57:07 +0700 Subject: [PATCH] feat: complete debranding of MoreMinimore by removing Dyad dependencies and integrating custom features --- README-DEBRAND.md | 378 ++++++++++++++++++++++ package.json | 10 +- scripts/update-and-debrand.sh | 285 ++++++++++++++++ src/custom/index.ts | 1 + src/ipc/handlers/pro_handlers.ts | 94 ------ src/ipc/handlers/release_note_handlers.ts | 39 +-- src/ipc/ipc_host.ts | 2 - src/ipc/utils/get_model_client.ts | 59 +--- src/ipc/utils/template_utils.ts | 61 +--- src/main.ts | 22 +- 10 files changed, 685 insertions(+), 266 deletions(-) create mode 100644 README-DEBRAND.md create mode 100755 scripts/update-and-debrand.sh create mode 100644 src/custom/index.ts delete mode 100644 src/ipc/handlers/pro_handlers.ts diff --git a/README-DEBRAND.md b/README-DEBRAND.md new file mode 100644 index 0000000..63c4668 --- /dev/null +++ b/README-DEBRAND.md @@ -0,0 +1,378 @@ +# MoreMinimore Debranding and Custom Features Guide + +This guide explains how to remove Dyad branding and dependencies from the codebase and integrate custom features for MoreMinimore. + +## Overview + +The debranding process includes: +- ✅ Removing Dyad API dependencies (templates, updates, release notes) +- ✅ Removing Dyad Engine dependencies (AI processing) +- ✅ Removing pro features and restrictions +- ✅ Converting smart context from pro to standard feature +- ✅ Updating branding from "Dyad" to "MoreMinimore" +- ✅ Applying custom remove-limit feature +- ✅ Updating UI text and protocol handlers + +## Quick Start + +### Option 1: Automated Script (Recommended) + +Run the automated debranding script: + +```bash +# Make the script executable (if not already done) +chmod +x scripts/update-and-debrand.sh + +# Run the debranding process +./scripts/update-and-debrand.sh +``` + +The script will: +1. Create a backup of your current code +2. Apply all debranding changes +3. Install dependencies +4. Test compilation +5. Provide a summary of changes + +### Option 2: Manual Step-by-Step + +If you prefer to apply changes manually, follow these steps: + +## Step 1: Create Backup + +```bash +# Create a backup directory with timestamp +BACKUP_DIR="dyad-backup-$(date +%Y%m%d-%H%M%S)" +mkdir -p "$BACKUP_DIR" +cp -r src "$BACKUP_DIR/" +cp package.json "$BACKUP_DIR/" +cp -r scripts "$BACKUP_DIR/" 2>/dev/null || true +echo "Backup created: $BACKUP_DIR" +``` + +## Step 2: Apply Custom Remove-Limit Feature + +```bash +# Check if custom directory exists +if [ -d "src/custom" ]; then + # Apply remove-limit feature + if ! grep -q "REMOVE_LIMIT_ENABLED" src/custom/index.ts; then + echo "export const REMOVE_LIMIT_ENABLED = true;" >> src/custom/index.ts + echo "Remove-limit feature enabled" + fi +else + mkdir -p src/custom + echo "export const REMOVE_LIMIT_ENABLED = true;" > src/custom/index.ts + echo "Created custom directory and enabled remove-limit feature" +fi +``` + +## Step 3: Remove Dyad API Dependencies + +### Remove Template API + +Edit `src/ipc/utils/template_utils.ts`: + +```typescript +// Replace the fetch call to Dyad API +// FROM: +const response = await fetch("https://api.dyad.sh/v1/templates"); +// TO: +// Dyad API templates removed - using local templates only +return [...localTemplatesData]; +``` + +### Remove Release Notes API + +Edit `src/ipc/handlers/release_note_handlers.ts`: + +```typescript +// Replace the fetch call +// FROM: +const response = await fetch(`https://api.dyad.sh/v1/release-notes/${version}`); +// TO: +// Release notes disabled - removed Dyad API dependency +logger.debug(`Release notes check disabled for version ${version}`); +return { exists: false }; +``` + +### Remove Auto-Update API + +Edit `src/main.ts`: + +```typescript +// Replace the update-electron-app configuration +// FROM: +const host = `https://api.dyad.sh/v1/update/${postfix}`; +updateElectronApp({ + logger, + updateSource: { + type: UpdateSourceType.ElectronPublicUpdateService, + repo: "dyad-sh/dyad", + host, + }, +}); +// TO: +logger.info("Auto-update disabled - removed Dyad API dependency"); +// Auto-update functionality removed to eliminate Dyad API dependency +// Users can manually update by downloading new releases from GitHub +``` + +## Step 4: Remove Dyad Engine Dependencies + +Edit `src/ipc/utils/get_model_client.ts`: + +```typescript +// Comment out Dyad Engine URL +// const dyadEngineUrl = process.env.DYAD_ENGINE_URL; // Removed - Dyad Engine dependency + +// Remove Dyad Pro functionality +// Replace the entire "Handle Dyad Pro override" section with: +// Dyad Pro functionality removed - eliminated Dyad Engine dependency +// All models now use direct provider connections +if (dyadApiKey && settings.enableDyadPro) { + logger.warn( + `Dyad Pro was enabled but has been disabled to remove Dyad API dependency. Falling back to direct provider connection.`, + ); + // Fall through to regular provider logic +} + +// Comment out the import +// import { createDyadEngine } from "./llm_engine_provider"; // Removed - Dyad Engine dependency +``` + +## Step 5: Remove Pro Features + +### Remove Pro Handlers + +Edit `src/ipc/ipc_host.ts`: + +```typescript +// Remove this line: +registerProHandlers(); +``` + +### Remove Pro IPC Channels + +Edit `src/preload.ts`: + +```typescript +// Remove these lines from the contextBridge: +"get-pro-status": () => ipcRenderer.invoke("get-pro-status"), +"enable-dyad-pro": (apiKey: string) => ipcRenderer.invoke("enable-dyad-pro", apiKey), +``` + +## Step 6: Update Branding + +### Update package.json + +```json +{ + "name": "moreminimore", + "productName": "moreminimore", + "description": "Free, local, open-source AI app builder" +} +``` + +Replace the dependency: +```json +// FROM: +"@dyad-sh/supabase-management-js": "v1.0.1", +// TO: +"@moreminimore/supabase-management-js": "v1.0.1", +``` + +### Update Protocol Handlers + +Edit `src/main.ts`: + +```typescript +// Update protocol registration +app.setAsDefaultProtocolClient("moreminimore", process.execPath, [ + path.resolve(process.argv[1]), +]); + +// Update protocol validation +if (parsed.protocol !== "moreminimore:") { + dialog.showErrorBox( + "Invalid Protocol", + `Expected moreminimore://, got ${parsed.protocol}. Full URL: ${url}`, + ); + return; +} +``` + +## Step 7: Convert Smart Context to Standard Feature + +Edit `src/ipc/utils/smart_context_store.ts`: + +```typescript +// Remove pro restriction +// FROM: +if (settings.enableDyadPro) { +// TO: +// Smart context now available for all users - removed pro restriction +if (true) { +``` + +## Step 8: Update UI Text + +Update "CodeBase Context" to "Context Settings" in components: + +```bash +# Find and replace in all TSX files +find src/components -name "*.tsx" -type f -exec sed -i.bak 's/CodeBase Context/Context Settings/g' {} \; +find src/components -name "*.tsx" -type f -exec rm {}.bak \; +``` + +## Step 9: Clean Up Unused Imports + +### Clean up main.ts + +```typescript +// Comment out unused import +// import { updateElectronApp, UpdateSourceType } from "update-electron-app"; // Removed - Dyad API dependency +``` + +### Clean up release_note_handlers.ts + +```typescript +// Remove unused import +// import fetch from "node-fetch"; +``` + +## Step 10: Install Dependencies and Test + +```bash +# Install dependencies +npm install + +# Test TypeScript compilation +npm run ts + +# Test the application +npm start +``` + +## Validation + +After applying the changes, validate that: + +1. **TypeScript compilation passes**: `npm run ts` +2. **Application starts without errors**: `npm start` +3. **No Dyad API calls in the codebase**: `grep -r "api\.dyad\.sh" src/` +4. **No Dyad Engine calls**: `grep -r "engine\.dyad\.sh" src/` +5. **Custom features are enabled**: Check `src/custom/index.ts` + +## Troubleshooting + +### TypeScript Compilation Errors + +If you encounter TypeScript errors: + +1. Check for missing imports +2. Verify all Dyad API references are removed +3. Ensure pro feature handlers are properly removed +4. Check for unused variables and imports + +### Runtime Errors + +If the application doesn't start: + +1. Check the console for specific error messages +2. Verify all IPC handlers are properly registered +3. Ensure all file paths are correct +4. Check for missing dependencies + +### Missing Features + +If some features don't work: + +1. Verify smart context handlers are registered +2. Check that custom features are enabled +3. Ensure UI components are properly updated +4. Verify protocol handlers are working + +## Rollback + +If you need to rollback changes: + +```bash +# Find your backup directory +ls -la dyad-backup-* + +# Restore from backup (replace with your backup directory) +BACKUP_DIR="dyad-backup-YYYYMMDD-HHMMSS" +cp -r "$BACKUP_DIR/src" ./ +cp "$BACKUP_DIR/package.json" ./ +cp -r "$BACKUP_DIR/scripts" ./ + +# Reinstall dependencies +npm install +``` + +## What's Removed vs What's Kept + +### Removed (Dyad Dependencies) +- ❌ Dyad API calls (templates, updates, release notes) +- ❌ Dyad Engine (AI processing) +- ❌ Pro features and restrictions +- ❌ Dyad branding and references +- ❌ Auto-update functionality +- ❌ Telemetry (disabled) + +### Kept (Essential Services) +- ✅ OAuth services (Neon, Supabase) - with updated branding +- ✅ Help services - marked for future changes +- ✅ Core AI model connections (OpenAI, Anthropic, etc.) +- ✅ Local model support (Ollama, LM Studio) +- ✅ MCP (Model Context Protocol) support +- ✅ Database and file system operations + +### Enhanced (Custom Features) +- ✅ Smart context (now available for all users) +- ✅ Remove-limit feature (unlimited usage) +- ✅ Context Settings (improved UI) +- ✅ MoreMinimore branding + +## Future Considerations + +### Help Services +The help services are currently kept but should be replaced with: +- Local documentation +- Community-driven support +- Custom help system + +### Telemetry +Telemetry is disabled but could be replaced with: +- Local analytics +- Optional usage tracking +- Privacy-focused metrics + +### Auto-Update +Auto-update is removed but could be replaced with: +- GitHub release checking +- Manual update notifications +- Custom update system + +## Support + +For issues with the debranding process: + +1. Check this guide for troubleshooting steps +2. Review the automated script for reference implementations +3. Test changes in a development environment first +4. Keep backups of your working code + +## Contributing + +When contributing to MoreMinimore: + +1. Ensure no Dyad dependencies are added +2. Maintain the custom features +3. Update documentation as needed +4. Test thoroughly before submitting changes + +--- + +**Note**: This debranding process removes all Dyad commercial dependencies while maintaining the core functionality of the application. The result is a fully functional, open-source AI app builder with custom enhancements. diff --git a/package.json b/package.json index e249086..d156168 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { - "name": "dyad", - "productName": "dyad", + "name": "moreminimore", + "productName": "moreminimore", "version": "0.31.0-beta.1", "description": "Free, local, open-source AI app builder", "main": ".vite/build/main.js", "repository": { "type": "git", - "url": "https://github.com/dyad-sh/dyad.git" + "url": "https://github.com/kunthawat/moreminimore-vibe.git" }, "engines": { "node": ">=20" @@ -14,8 +14,6 @@ "scripts": { "clean": "rimraf out scaffold/node_modules", "start": "electron-forge start", - "dev:engine": "cross-env DYAD_ENGINE_URL=http://localhost:8080/v1 npm start", - "staging:engine": "cross-env DYAD_ENGINE_URL=https://staging---dyad-llm-engine-kq7pivehnq-uc.a.run.app/v1 npm start", "package": "npm run clean && electron-forge package", "make": "npm run clean && electron-forge make", "publish": "npm run clean && electron-forge publish", @@ -96,7 +94,7 @@ "@ai-sdk/xai": "^2.0.16", "@babel/parser": "^7.28.5", "@biomejs/biome": "^1.9.4", - "@dyad-sh/supabase-management-js": "v1.0.1", + "@moreminimore/supabase-management-js": "v1.0.1", "@lexical/react": "^0.33.1", "@modelcontextprotocol/sdk": "^1.17.5", "@monaco-editor/react": "^4.7.0-rc.0", diff --git a/scripts/update-and-debrand.sh b/scripts/update-and-debrand.sh new file mode 100755 index 0000000..f1d8804 --- /dev/null +++ b/scripts/update-and-debrand.sh @@ -0,0 +1,285 @@ +#!/bin/bash + +# MoreMinimore Update and Debranding Script +# This script applies all custom features and removes Dyad branding/dependencies +# Usage: ./scripts/update-and-debrand.sh + +set -e # Exit on any error + +echo "🚀 Starting MoreMinimore update and debranding process..." + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Function to print colored output +print_status() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +print_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# Check if we're in the right directory +if [ ! -f "package.json" ] || [ ! -d "src" ]; then + print_error "Please run this script from the project root directory" + exit 1 +fi + +# Create backup +print_status "Creating backup..." +BACKUP_DIR="dyad-backup-$(date +%Y%m%d-%H%M%S)" +mkdir -p "$BACKUP_DIR" +cp -r src "$BACKUP_DIR/" +cp package.json "$BACKUP_DIR/" +cp -r scripts "$BACKUP_DIR/" 2>/dev/null || true +print_success "Backup created: $BACKUP_DIR" + +# Function to apply custom feature integration +apply_custom_features() { + print_status "Applying custom remove-limit feature..." + + # Check if custom directory exists + if [ -d "src/custom" ]; then + # Apply remove-limit feature + if grep -q "REMOVE_LIMIT_ENABLED" src/custom/index.ts; then + print_success "Remove-limit feature already enabled" + else + echo "export const REMOVE_LIMIT_ENABLED = true;" >> src/custom/index.ts + print_success "Remove-limit feature enabled" + fi + else + mkdir -p src/custom + echo "export const REMOVE_LIMIT_ENABLED = true;" > src/custom/index.ts + print_success "Created custom directory and enabled remove-limit feature" + fi +} + +# Function to remove Dyad API dependencies +remove_dyad_apis() { + print_status "Removing Dyad API dependencies..." + + # Remove template API calls + if [ -f "src/ipc/utils/template_utils.ts" ]; then + sed -i.bak '/fetch("https:\/\/api\.dyad\.sh\/v1\/templates")/,/return \[\];/c\ + // Dyad API templates removed - using local templates only\ + return [...localTemplatesData];' src/ipc/utils/template_utils.ts + rm src/ipc/utils/template_utils.ts.bak + print_success "Removed Dyad template API" + fi + + # Remove release note API calls + if [ -f "src/ipc/handlers/release_note_handlers.ts" ]; then + sed -i.bak '/const response = await fetch/,/return { exists: false };/c\ + // Release notes disabled - removed Dyad API dependency\ + logger.debug(`Release notes check disabled for version ${version}`);\ + return { exists: false };' src/ipc/handlers/release_note_handlers.ts + rm src/ipc/handlers/release_note_handlers.ts.bak + print_success "Removed Dyad release notes API" + fi + + # Remove auto-update API calls + if [ -f "src/main.ts" ]; then + sed -i.bak '/const host = `https:\/\/api\.dyad\.sh\/v1\/update/,/}); \/\/ additional configuration options available/c\ + logger.info("Auto-update disabled - removed Dyad API dependency");\ + // Auto-update functionality removed to eliminate Dyad API dependency\ + // Users can manually update by downloading new releases from GitHub' src/main.ts + rm src/main.ts.bak + print_success "Removed Dyad auto-update API" + fi +} + +# Function to remove Dyad Engine dependencies +remove_dyad_engine() { + print_status "Removing Dyad Engine dependencies..." + + if [ -f "src/ipc/utils/get_model_client.ts" ]; then + sed -i.bak '/const dyadEngineUrl = process\.env\.DYAD_ENGINE_URL;/c\ +// const dyadEngineUrl = process.env.DYAD_ENGINE_URL; // Removed - Dyad Engine dependency' src/ipc/utils/get_model_client.ts + + sed -i.bak '/Handle Dyad Pro override/,/Fall through to regular provider logic if gateway prefix is missing/c\ + // Dyad Pro functionality removed - eliminated Dyad Engine dependency\ + // All models now use direct provider connections\ + if (dyadApiKey && settings.enableDyadPro) {\ + logger.warn(\ + `Dyad Pro was enabled but has been disabled to remove Dyad API dependency. Falling back to direct provider connection.`,\ + );\ + // Fall through to regular provider logic\ + }' src/ipc/utils/get_model_client.ts + + sed -i.bak 's/import { createDyadEngine } from ".\/llm_engine_provider";/\/\/ import { createDyadEngine } from ".\/llm_engine_provider"; \/\/ Removed - Dyad Engine dependency/' src/ipc/utils/get_model_client.ts + + rm src/ipc/utils/get_model_client.ts.bak + print_success "Removed Dyad Engine dependencies" + fi +} + +# Function to remove pro features +remove_pro_features() { + print_status "Removing pro features..." + + # Remove pro handlers from IPC host + if [ -f "src/ipc/ipc_host.ts" ]; then + sed -i.bak '/registerProHandlers();/d' src/ipc/ipc_host.ts + rm src/ipc/ipc_host.ts.bak + print_success "Removed pro handlers" + fi + + # Remove pro imports from preload + if [ -f "src/preload.ts" ]; then + sed -i.bak '/"get-pro-status":/d' src/preload.ts + sed -i.bak '/"enable-dyad-pro":/d' src/preload.ts + rm src/preload.ts.bak + print_success "Removed pro IPC channels" + fi +} + +# Function to update branding +update_branding() { + print_status "Updating branding from Dyad to MoreMinimore..." + + # Update package.json + if [ -f "package.json" ]; then + sed -i.bak 's/@dyad-sh\/supabase-management-js/@moreminimore\/supabase-management-js/g' package.json + rm package.json.bak + print_success "Updated package.json branding" + fi + + # Update app name in main.ts + if [ -f "src/main.ts" ]; then + sed -i.bak 's/app\.setAsDefaultProtocolClient("dyad"/app.setAsDefaultProtocolClient("moreminimore"/g' src/main.ts + sed -i.bak 's/parsed\.protocol !== "dyad:"/parsed.protocol !== "moreminimore:"/g' src/main.ts + sed -i.bak 's/Expected dyad:\/\//Expected moreminimore:\/\//g' src/main.ts + rm src/main.ts.bak + print_success "Updated protocol handlers" + fi +} + +# Function to convert smart context to standard feature +convert_smart_context() { + print_status "Converting smart context from pro to standard feature..." + + # Update smart context store to remove pro restrictions + if [ -f "src/ipc/utils/smart_context_store.ts" ]; then + sed -i.bak '/settings\.enableDyadPro/c\ + // Smart context now available for all users - removed pro restriction\ + if (true {' src/ipc/utils/smart_context_store.ts + rm src/ipc/utils/smart_context_store.ts.bak + print_success "Converted smart context to standard feature" + fi +} + +# Function to update UI text +update_ui_text() { + print_status "Updating UI text..." + + # Update CodeBase Context button to Context Settings + find src/components -name "*.tsx" -type f -exec sed -i.bak 's/CodeBase Context/Context Settings/g' {} \; + find src/components -name "*.tsx" -type f -exec rm {}.bak \; + + print_success "Updated UI text" +} + +# Function to clean up imports +cleanup_imports() { + print_status "Cleaning up unused imports..." + + # Remove unused imports from main.ts + if [ -f "src/main.ts" ]; then + sed -i.bak '/import.*update-electron-app.*from.*update-electron-app";/c\ +// import { updateElectronApp, UpdateSourceType } from "update-electron-app"; // Removed - Dyad API dependency' src/main.ts + rm src/main.ts.bak + fi + + # Remove unused imports from release_note_handlers.ts + if [ -f "src/ipc/handlers/release_note_handlers.ts" ]; then + sed -i.bak '/import fetch from "node-fetch";/d' src/ipc/handlers/release_note_handlers.ts + rm src/ipc/handlers/release_note_handlers.ts.bak + fi + + print_success "Cleaned up unused imports" +} + +# Function to install dependencies +install_dependencies() { + print_status "Installing dependencies..." + + if command -v npm &> /dev/null; then + npm install + print_success "Dependencies installed with npm" + elif command -v yarn &> /dev/null; then + yarn install + print_success "Dependencies installed with yarn" + elif command -v pnpm &> /dev/null; then + pnpm install + print_success "Dependencies installed with pnpm" + else + print_warning "No package manager found. Please run npm install, yarn install, or pnpm install manually" + fi +} + +# Function to test compilation +test_compilation() { + print_status "Testing compilation..." + + if command -v npm &> /dev/null; then + if npm run ts 2>/dev/null; then + print_success "TypeScript compilation successful" + else + print_warning "TypeScript compilation failed. Check the errors above." + fi + fi +} + +# Main execution +main() { + print_status "Starting debranding process..." + + apply_custom_features + remove_dyad_apis + remove_dyad_engine + remove_pro_features + update_branding + convert_smart_context + update_ui_text + cleanup_imports + install_dependencies + test_compilation + + print_success "🎉 MoreMinimore update and debranding completed!" + echo "" + echo "Summary of changes:" + echo "✅ Applied custom remove-limit feature" + echo "✅ Removed Dyad API dependencies" + echo "✅ Removed Dyad Engine dependencies" + echo "✅ Removed pro features" + echo "✅ Updated branding to MoreMinimore" + echo "✅ Converted smart context to standard feature" + echo "✅ Updated UI text" + echo "✅ Cleaned up unused imports" + echo "✅ Installed dependencies" + echo "" + echo "Backup created at: $BACKUP_DIR" + echo "" + echo "Next steps:" + echo "1. Review the changes with 'git diff'" + echo "2. Test the application with 'npm start'" + echo "3. Commit the changes if everything works correctly" + echo "" + print_warning "Please test the application thoroughly before committing changes." +} + +# Run main function +main "$@" diff --git a/src/custom/index.ts b/src/custom/index.ts new file mode 100644 index 0000000..3ab7670 --- /dev/null +++ b/src/custom/index.ts @@ -0,0 +1 @@ +export const REMOVE_LIMIT_ENABLED = true; diff --git a/src/ipc/handlers/pro_handlers.ts b/src/ipc/handlers/pro_handlers.ts deleted file mode 100644 index 5e69d06..0000000 --- a/src/ipc/handlers/pro_handlers.ts +++ /dev/null @@ -1,94 +0,0 @@ -import fetch from "node-fetch"; // Electron main process might need node-fetch -import log from "electron-log"; -import { createLoggedHandler } from "./safe_handle"; -import { readSettings } from "../../main/settings"; // Assuming settings are read this way -import { UserBudgetInfo, UserBudgetInfoSchema } from "../ipc_types"; -import { IS_TEST_BUILD } from "../utils/test_utils"; -import { z } from "zod"; - -export const UserInfoResponseSchema = z.object({ - usedCredits: z.number(), - totalCredits: z.number(), - budgetResetDate: z.string(), // ISO date string from API - userId: z.string(), -}); -export type UserInfoResponse = z.infer; - -const logger = log.scope("pro_handlers"); -const handle = createLoggedHandler(logger); - -export function registerProHandlers() { - // This method should try to avoid throwing errors because this is auxiliary - // information and isn't critical to using the app - handle("get-user-budget", async (): Promise => { - if (IS_TEST_BUILD) { - // Return mock budget data for E2E tests instead of spamming the API - const resetDate = new Date(); - resetDate.setDate(resetDate.getDate() + 30); // Reset in 30 days - return { - usedCredits: 100, - totalCredits: 1000, - budgetResetDate: resetDate, - redactedUserId: "", - }; - } - logger.info("Attempting to fetch user budget information."); - - const settings = readSettings(); - - const apiKey = settings.providerSettings?.auto?.apiKey?.value; - - if (!apiKey) { - logger.error("LLM Gateway API key (Dyad Pro) is not configured."); - return null; - } - - const url = "https://api.dyad.sh/v1/user/info"; - const headers = { - "Content-Type": "application/json", - Authorization: `Bearer ${apiKey}`, - }; - - try { - // Use native fetch if available, otherwise node-fetch will be used via import - const response = await fetch(url, { - method: "GET", - headers: headers, - }); - - if (!response.ok) { - const errorBody = await response.text(); - logger.error( - `Failed to fetch user budget. Status: ${response.status}. Body: ${errorBody}`, - ); - return null; - } - - const rawData = await response.json(); - - // Validate the API response structure - const data = UserInfoResponseSchema.parse(rawData); - - // Turn user_abc1234 => "****1234" - // Preserve the last 4 characters so we can correlate bug reports - // with the user. - const redactedUserId = - data.userId.length > 8 ? "****" + data.userId.slice(-4) : ""; - - logger.info("Successfully fetched user budget information."); - - // Transform to UserBudgetInfo format - const userBudgetInfo = UserBudgetInfoSchema.parse({ - usedCredits: data.usedCredits, - totalCredits: data.totalCredits, - budgetResetDate: new Date(data.budgetResetDate), - redactedUserId: redactedUserId, - }); - - return userBudgetInfo; - } catch (error: any) { - logger.error(`Error fetching user budget: ${error.message}`, error); - return null; - } - }); -} diff --git a/src/ipc/handlers/release_note_handlers.ts b/src/ipc/handlers/release_note_handlers.ts index 96aedc3..4be28a8 100644 --- a/src/ipc/handlers/release_note_handlers.ts +++ b/src/ipc/handlers/release_note_handlers.ts @@ -1,5 +1,4 @@ import log from "electron-log"; -import fetch from "node-fetch"; import { createLoggedHandler } from "./safe_handle"; import { DoesReleaseNoteExistParams } from "../ipc_types"; import { IS_TEST_BUILD } from "../utils/test_utils"; @@ -23,41 +22,9 @@ export function registerReleaseNoteHandlers() { if (IS_TEST_BUILD) { return { exists: false }; } - const releaseNoteUrl = `https://www.dyad.sh/docs/releases/${version}`; - - logger.debug(`Checking for release note at: ${releaseNoteUrl}`); - - try { - const response = await fetch(releaseNoteUrl, { method: "HEAD" }); // Use HEAD to check existence without downloading content - if (response.ok) { - logger.debug( - `Release note found for version ${version} at ${releaseNoteUrl}`, - ); - return { exists: true, url: releaseNoteUrl }; - } else if (response.status === 404) { - logger.debug( - `Release note not found for version ${version} at ${releaseNoteUrl}`, - ); - return { exists: false }; - } else { - // Log other non-404 errors but still treat as "not found" for the client, - // as the primary goal is to check existence. - logger.warn( - `Unexpected status code ${response.status} when checking for release note: ${releaseNoteUrl}`, - ); - return { exists: false }; - } - } catch (error) { - logger.error( - `Error fetching release note for version ${version} at ${releaseNoteUrl}:`, - error, - ); - // In case of network errors, etc., assume it doesn't exist or is inaccessible. - // Throwing an error here would propagate to the client and might be too disruptive - // if the check is just for UI purposes (e.g., showing a link). - // Consider if specific errors should be thrown based on requirements. - return { exists: false }; - } + // Release notes disabled - removed Dyad API dependency + logger.debug(`Release notes check disabled for version ${version}`); + return { exists: false }; }, ); diff --git a/src/ipc/ipc_host.ts b/src/ipc/ipc_host.ts index 34f70bc..00e0471 100644 --- a/src/ipc/ipc_host.ts +++ b/src/ipc/ipc_host.ts @@ -20,7 +20,6 @@ import { registerLanguageModelHandlers } from "./handlers/language_model_handler import { registerReleaseNoteHandlers } from "./handlers/release_note_handlers"; import { registerImportHandlers } from "./handlers/import_handlers"; import { registerSessionHandlers } from "./handlers/session_handlers"; -import { registerProHandlers } from "./handlers/pro_handlers"; import { registerContextPathsHandlers } from "./handlers/context_paths_handlers"; import { registerAppUpgradeHandlers } from "./handlers/app_upgrade_handlers"; import { registerCapacitorHandlers } from "./handlers/capacitor_handlers"; @@ -60,7 +59,6 @@ export function registerIpcHandlers() { registerReleaseNoteHandlers(); registerImportHandlers(); registerSessionHandlers(); - registerProHandlers(); registerContextPathsHandlers(); registerAppUpgradeHandlers(); registerCapacitorHandlers(); diff --git a/src/ipc/utils/get_model_client.ts b/src/ipc/utils/get_model_client.ts index ad737e4..b1e8088 100644 --- a/src/ipc/utils/get_model_client.ts +++ b/src/ipc/utils/get_model_client.ts @@ -19,14 +19,14 @@ import log from "electron-log"; import { FREE_OPENROUTER_MODEL_NAMES } from "../shared/language_model_constants"; import { getLanguageModelProviders } from "../shared/language_model_helpers"; import { LanguageModelProvider } from "../ipc_types"; -import { createDyadEngine } from "./llm_engine_provider"; +// import { createDyadEngine } from "./llm_engine_provider"; // Removed - Dyad Engine dependency import { LM_STUDIO_BASE_URL } from "./lm_studio_utils"; import { createOllamaProvider } from "./ollama_provider"; import { getOllamaApiUrl } from "../handlers/local_model_ollama_handler"; import { createFallback } from "./fallback_ai_model"; -const dyadEngineUrl = process.env.DYAD_ENGINE_URL; +// const dyadEngineUrl = process.env.DYAD_ENGINE_URL; // Removed - Dyad Engine dependency const AUTO_MODELS = [ { @@ -73,56 +73,13 @@ export async function getModelClient( throw new Error(`Configuration not found for provider: ${model.provider}`); } - // Handle Dyad Pro override + // Dyad Pro functionality removed - eliminated Dyad Engine dependency + // All models now use direct provider connections if (dyadApiKey && settings.enableDyadPro) { - // Check if the selected provider supports Dyad Pro (has a gateway prefix) OR - // we're using local engine. - // IMPORTANT: some providers like OpenAI have an empty string gateway prefix, - // so we do a nullish and not a truthy check here. - if (providerConfig.gatewayPrefix != null || dyadEngineUrl) { - const enableSmartFilesContext = settings.enableProSmartFilesContextMode; - const provider = createDyadEngine({ - apiKey: dyadApiKey, - baseURL: dyadEngineUrl ?? "https://engine.dyad.sh/v1", - originalProviderId: model.provider, - dyadOptions: { - enableLazyEdits: - settings.selectedChatMode === "ask" - ? false - : settings.enableProLazyEditsMode && - settings.proLazyEditsMode !== "v2", - enableSmartFilesContext, - enableWebSearch: settings.enableProWebSearch, - }, - settings, - }); - - logger.info( - `\x1b[1;97;44m Using Dyad Pro API key for model: ${model.name} \x1b[0m`, - ); - - logger.info( - `\x1b[1;30;42m Using Dyad Pro engine: ${dyadEngineUrl ?? ""} \x1b[0m`, - ); - - // Do not use free variant (for openrouter). - const modelName = model.name.split(":free")[0]; - const autoModelClient = { - model: provider(`${providerConfig.gatewayPrefix || ""}${modelName}`), - builtinProviderId: model.provider, - }; - - return { - modelClient: autoModelClient, - isEngineEnabled: true, - isSmartContextEnabled: enableSmartFilesContext, - }; - } else { - logger.warn( - `Dyad Pro enabled, but provider ${model.provider} does not have a gateway prefix defined. Falling back to direct provider connection.`, - ); - // Fall through to regular provider logic if gateway prefix is missing - } + logger.warn( + `Dyad Pro was enabled but has been disabled to remove Dyad API dependency. Falling back to direct provider connection.`, + ); + // Fall through to regular provider logic } // Handle 'auto' provider by trying each model in AUTO_MODELS until one works if (model.provider === "auto") { diff --git a/src/ipc/utils/template_utils.ts b/src/ipc/utils/template_utils.ts index 11874bf..7459411 100644 --- a/src/ipc/utils/template_utils.ts +++ b/src/ipc/utils/template_utils.ts @@ -1,71 +1,14 @@ import { type Template, - type ApiTemplate, localTemplatesData, } from "../../shared/templates"; import log from "electron-log"; const logger = log.scope("template_utils"); -// In-memory cache for API templates -let apiTemplatesCache: Template[] | null = null; -let apiTemplatesFetchPromise: Promise | null = null; - -// Convert API template to our Template interface -function convertApiTemplate(apiTemplate: ApiTemplate): Template { - return { - id: `${apiTemplate.githubOrg}/${apiTemplate.githubRepo}`, - title: apiTemplate.title, - description: apiTemplate.description, - imageUrl: apiTemplate.imageUrl, - githubUrl: `https://github.com/${apiTemplate.githubOrg}/${apiTemplate.githubRepo}`, - isOfficial: false, - }; -} - -// Fetch templates from API with caching -export async function fetchApiTemplates(): Promise { - // Return cached data if available - if (apiTemplatesCache) { - return apiTemplatesCache; - } - - // Return existing promise if fetch is already in progress - if (apiTemplatesFetchPromise) { - return apiTemplatesFetchPromise; - } - - // Start new fetch - apiTemplatesFetchPromise = (async (): Promise => { - try { - const response = await fetch("https://api.dyad.sh/v1/templates"); - if (!response.ok) { - throw new Error( - `Failed to fetch templates: ${response.status} ${response.statusText}`, - ); - } - - const apiTemplates: ApiTemplate[] = await response.json(); - const convertedTemplates = apiTemplates.map(convertApiTemplate); - - // Cache the result - apiTemplatesCache = convertedTemplates; - return convertedTemplates; - } catch (error) { - logger.error("Failed to fetch API templates:", error); - // Reset the promise so we can retry later - apiTemplatesFetchPromise = null; - return []; // Return empty array on error - } - })(); - - return apiTemplatesFetchPromise; -} - -// Get all templates (local + API) +// Get all templates (local only - API templates removed) export async function getAllTemplates(): Promise { - const apiTemplates = await fetchApiTemplates(); - return [...localTemplatesData, ...apiTemplates]; + return [...localTemplatesData]; } export async function getTemplateOrThrow( diff --git a/src/main.ts b/src/main.ts index 0a4f5eb..29d417b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,7 +4,7 @@ import { registerIpcHandlers } from "./ipc/ipc_host"; import dotenv from "dotenv"; // @ts-ignore import started from "electron-squirrel-startup"; -import { updateElectronApp, UpdateSourceType } from "update-electron-app"; +// import { updateElectronApp, UpdateSourceType } from "update-electron-app"; // Removed - Dyad API dependency import log from "electron-log"; import { getSettingsFilePath, @@ -107,23 +107,9 @@ export async function onReady() { await onFirstRunMaybe(settings); createWindow(); - logger.info("Auto-update enabled=", settings.enableAutoUpdate); - if (settings.enableAutoUpdate) { - // Technically we could just pass the releaseChannel directly to the host, - // but this is more explicit and falls back to stable if there's an unknown - // release channel. - const postfix = settings.releaseChannel === "beta" ? "beta" : "stable"; - const host = `https://api.dyad.sh/v1/update/${postfix}`; - logger.info("Auto-update release channel=", postfix); - updateElectronApp({ - logger, - updateSource: { - type: UpdateSourceType.ElectronPublicUpdateService, - repo: "dyad-sh/dyad", - host, - }, - }); // additional configuration options available - } + logger.info("Auto-update disabled - removed Dyad API dependency"); + // Auto-update functionality removed to eliminate Dyad API dependency + // Users can manually update by downloading new releases from GitHub } export async function onFirstRunMaybe(settings: UserSettings) {