Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
919d9a4
Implement V2 realtime agent with OpenAI Agents SDK
vijaythecoder Jul 20, 2025
7f2c6ea
Refactor RealtimeAgent to component architecture with Pinia stores
vijaythecoder Jul 20, 2025
85e1001
Add mock data system for RealtimeAgent V2 testing
vijaythecoder Jul 21, 2025
1686712
Fix RealtimeAgent V2 layout and overlay mode issues
vijaythecoder Jul 21, 2025
51daab6
Fix mobile layout and consistent card backgrounds
vijaythecoder Jul 21, 2025
df31ac6
Fix realtime analytics and improve responsiveness
vijaythecoder Jul 21, 2025
abcc11e
Remove REALTIME_ARCHITECTURE.md file
vijaythecoder Jul 21, 2025
642ee0e
Fix ESLint errors across multiple files
vijaythecoder Jul 21, 2025
fe91d8e
Fix realtime analytics and improve responsiveness
vijaythecoder Jul 21, 2025
ddf83a8
Update all links to point to new RealtimeAgent V2
vijaythecoder Jul 21, 2025
db8903b
feat: integrate electron-audio-loopback and fix permissions
vijaythecoder Jul 22, 2025
ca6d7f2
refactor: clean up navigation and improve UX
vijaythecoder Jul 22, 2025
2018f5d
refactor: remove excessive logging from MainV2.vue
vijaythecoder Jul 22, 2025
17fe3b5
fix: resolve npm build error in MainV2.vue
vijaythecoder Jul 22, 2025
3cec110
fix: resolve ESLint errors
vijaythecoder Jul 22, 2025
7c102dd
refactor: remove unnecessary debug logging from production code
vijaythecoder Jul 23, 2025
3fde92d
refactor: update MainV2.vue to use Native.ipcRendererInvoke
vijaythecoder Jul 24, 2025
0acd667
fix: resolve system audio capture issue in realtime agent
vijaythecoder Jul 25, 2025
f01facf
improvements on teh nativephp extension
vijaythecoder Jul 25, 2025
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ yarn-error.log
/.zed
/dist
.DS_Store

# NativePHP local development
nativephp-electron/
281 changes: 281 additions & 0 deletions NATIVEPHP_EXTENSIBILITY_PROPOSAL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
# NativePHP Extensibility System Proposal

## Executive Summary

This proposal introduces a plugin/extension system for NativePHP that allows developers to extend Electron functionality without modifying vendor files. This solves a critical pain point where developers currently must fork NativePHP or lose customizations on updates.

## Problem Statement

Currently, developers who need to extend NativePHP's Electron functionality must:
- ❌ Modify vendor files (lost on composer update)
- ❌ Fork the entire package (maintenance burden)
- ❌ Use hacky workarounds
- ❌ Give up on advanced Electron features

**Real examples from the community:**
- "How do I add custom IPC handlers?"
- "I need to initialize electron-audio-loopback before app ready"
- "How can I add a system tray without forking?"
- "I want to register a custom protocol handler"

## Proposed Solution

### Extension File Structure

Developers create extension files in their project (not vendor):

```javascript
// resources/js/nativephp-extension.js
export default {
// Hook into Electron lifecycle
beforeReady: (app) => {
// Initialize things before app is ready
// e.g., protocol registration, early IPC handlers
},

afterReady: (app, mainWindow) => {
// Setup after app is ready
// e.g., tray icons, global shortcuts, window customization
},

beforeQuit: () => {
// Cleanup before app quits
},

// Custom IPC handlers
ipcHandlers: {
'my-app:custom-action': async (event, ...args) => {
// Handle custom IPC calls from renderer
return { success: true, data: 'result' };
}
},

// Custom API endpoints
apiRoutes: (router) => {
router.post('/api/my-app/custom-endpoint', (req, res) => {
// Handle HTTP requests from Laravel
res.json({ status: 'ok' });
});
},

// Extend preload script
preload: {
exposeAPIs: {
myApp: {
doSomething: () => ipcRenderer.invoke('my-app:custom-action'),
getSomething: () => ipcRenderer.invoke('my-app:get-data')
}
}
}
};
```

### Implementation in NativePHP Core

Only ~100 lines of changes needed across 4 files:

#### 1. New Extension Loader (50 lines)
```typescript
// electron-plugin/src/extensions/loader.ts
export async function loadUserExtensions() {
const extensions = [];

// Load single extension file
const singleExtPath = path.join(process.cwd(), 'resources/js/nativephp-extension.js');
if (fs.existsSync(singleExtPath)) {
extensions.push(require(singleExtPath).default);
}

// Load from extensions directory
const extensionsDir = path.join(process.cwd(), 'resources/js/nativephp-extensions');
if (fs.existsSync(extensionsDir)) {
// Load all .js files as extensions
}

return extensions;
}
```

#### 2. Hook into Main Process (15 lines added)
```typescript
// electron-plugin/src/index.ts
const extensions = await loadUserExtensions();

// Before app ready
for (const ext of extensions) {
if (ext.beforeReady) await ext.beforeReady(app);
}

// After app ready
app.whenReady().then(() => {
for (const ext of extensions) {
if (ext.afterReady) await ext.afterReady(app, mainWindow);

// Register IPC handlers
if (ext.ipcHandlers) {
Object.entries(ext.ipcHandlers).forEach(([channel, handler]) => {
ipcMain.handle(channel, handler);
});
}
}
});
```

#### 3. API Routes (10 lines added)
```typescript
// electron-plugin/src/server/index.ts
const extensions = await loadUserExtensions();
for (const ext of extensions) {
if (ext.apiRoutes) {
const router = Router();
ext.apiRoutes(router);
app.use(router);
}
}
```

#### 4. Preload Extensions (20 lines added)
```typescript
// electron-plugin/src/preload/index.mts
const preloadPath = path.join(__dirname, '../../../resources/js/nativephp-preload.js');
if (fs.existsSync(preloadPath)) {
const userPreload = require(preloadPath);
if (userPreload.exposeAPIs) {
Object.entries(userPreload.exposeAPIs).forEach(([name, api]) => {
contextBridge.exposeInMainWorld(name, api);
});
}
}
```

## Real-World Examples

### Example 1: Audio Capture Extension
```javascript
import { initMain as initAudioLoopback } from "electron-audio-loopback";

export default {
beforeReady: (app) => {
initAudioLoopback(); // Initialize before app ready
},

ipcHandlers: {
'audio:enable-loopback': async () => {
// Implementation
return { enabled: true };
}
},

apiRoutes: (router) => {
router.post('/api/audio/enable', (req, res) => {
// Enable system audio capture
res.json({ status: 'enabled' });
});
}
};
```

### Example 2: System Tray Extension
```javascript
import { Tray, Menu } from 'electron';

let tray = null;

export default {
afterReady: (app, mainWindow) => {
tray = new Tray('/path/to/icon.png');
tray.setToolTip('My App');

const menu = Menu.buildFromTemplate([
{ label: 'Show', click: () => mainWindow.show() },
{ label: 'Quit', click: () => app.quit() }
]);

tray.setContextMenu(menu);
}
};
```

### Example 3: Global Shortcuts
```javascript
import { globalShortcut } from 'electron';

export default {
afterReady: (app, mainWindow) => {
globalShortcut.register('CommandOrControl+Shift+Y', () => {
mainWindow.webContents.send('shortcut:triggered');
});
},

beforeQuit: () => {
globalShortcut.unregisterAll();
}
};
```

## Benefits

### For Developers
- βœ… **No vendor modifications** - Extensions live in your codebase
- βœ… **Survives updates** - Composer update won't break customizations
- βœ… **Full Electron access** - Use any Electron API
- βœ… **Shareable** - Package and share extensions

### For NativePHP
- βœ… **Reduces fork pressure** - Fewer reasons to fork
- βœ… **Enables ecosystem** - Community can build extensions
- βœ… **Keeps core lean** - Features as extensions, not core
- βœ… **Innovation platform** - Developers can experiment

## Security Considerations

- Extensions run in main process (full access like app code)
- No additional security risks (developers already have full access)
- Optional: Add permission system in future versions

## Backwards Compatibility

- βœ… Fully backwards compatible
- βœ… No breaking changes
- βœ… Extensions are opt-in
- βœ… Existing apps work unchanged

## Implementation Plan

1. **Week 1**: Core implementation
- Extension loader
- Lifecycle hooks
- IPC handler registration

2. **Week 2**: API integration
- API route registration
- Preload extensions
- Error handling

3. **Week 3**: Documentation
- Extension guide
- API reference
- Example extensions

4. **Week 4**: Community
- Example repository
- Video tutorials
- Community feedback

## Future Enhancements

- Extension dependencies management
- Extension marketplace/registry
- GUI for managing extensions
- Hot-reload during development
- TypeScript definitions

## Summary

This minimal change (~100 lines) would:
- Solve a major developer pain point
- Enable unlimited extensibility
- Build a thriving ecosystem
- Position NativePHP as the most flexible Electron framework

The implementation is simple, backwards compatible, and opens up endless possibilities for the community.
Loading
Loading