5 Commits

Author SHA1 Message Date
simos
1f4cd16b89 fix: change agent mode for platform 2025-12-10 00:29:53 +01:00
viper151
09688a09ca Merge pull request #253 from siteboon/viper151-patch-1
Update App.jsx
2025-12-07 07:49:36 +01:00
viper151
1cc3f61b81 Update App.jsx 2025-12-07 07:49:08 +01:00
simos
3a72a262a9 logo color change 2025-11-19 09:10:41 +01:00
simosmik
e952cf0a42 feat(terminal): add clickable web links support
Replace ClipboardAddon with WebLinksAddon to enable automatic
detection and clickable handling of URLs in terminal output.
This improves user experience by allowing direct interaction with
links displayed in the terminal.
2025-11-18 20:29:30 +00:00
11 changed files with 65 additions and 17 deletions

10
package-lock.json generated
View File

@@ -24,6 +24,7 @@
"@uiw/react-codemirror": "^4.23.13",
"@xterm/addon-clipboard": "^0.1.0",
"@xterm/addon-fit": "^0.10.0",
"@xterm/addon-web-links": "^0.11.0",
"@xterm/addon-webgl": "^0.18.0",
"@xterm/xterm": "^5.5.0",
"bcrypt": "^6.0.0",
@@ -3024,6 +3025,15 @@
"@xterm/xterm": "^5.0.0"
}
},
"node_modules/@xterm/addon-web-links": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@xterm/addon-web-links/-/addon-web-links-0.11.0.tgz",
"integrity": "sha512-nIHQ38pQI+a5kXnRaTgwqSHnX7KE6+4SVoceompgHL26unAxdfP6IPqUTSYPQgSwM56hsElfoNrrW5V7BUED/Q==",
"license": "MIT",
"peerDependencies": {
"@xterm/xterm": "^5.0.0"
}
},
"node_modules/@xterm/addon-webgl": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/@xterm/addon-webgl/-/addon-webgl-0.18.0.tgz",

View File

@@ -55,6 +55,7 @@
"@uiw/react-codemirror": "^4.23.13",
"@xterm/addon-clipboard": "^0.1.0",
"@xterm/addon-fit": "^0.10.0",
"@xterm/addon-web-links": "^0.11.0",
"@xterm/addon-webgl": "^0.18.0",
"@xterm/xterm": "^5.5.0",
"bcrypt": "^6.0.0",

BIN
public/logo-128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
public/logo-256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
public/logo-32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 B

BIN
public/logo-512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

BIN
public/logo-64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 870 B

View File

@@ -1,9 +1,17 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="32" height="32" rx="8" fill="hsl(262.1 83.3% 57.8%)"/>
<path d="M8 9C8 8.44772 8.44772 8 9 8H23C23.5523 8 24 8.44772 24 9V18C24 18.5523 23.5523 19 23 19H12L8 23V9Z"
<svg
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
>
<rect width="32" height="32" rx="8" fill="hsl(221.2 83.2% 53.3%)"/>
<path
d="M8 9C8 8.44772 8.44772 8 9 8H23C23.5523 8 24 8.44772 24 9V18C24 18.5523 23.5523 19 23 19H12L8 23V9Z"
stroke="white"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
fill="none"/>
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
fill="none"
/>
</svg>

Before

Width:  |  Height:  |  Size: 422 B

After

Width:  |  Height:  |  Size: 413 B

View File

@@ -4,7 +4,7 @@ import path from 'path';
import os from 'os';
import { promises as fs } from 'fs';
import crypto from 'crypto';
import { apiKeysDb, githubTokensDb } from '../database/db.js';
import { userDb, apiKeysDb, githubTokensDb } from '../database/db.js';
import { addProjectManually } from '../projects.js';
import { queryClaudeSDK } from '../claude-sdk.js';
import { spawnCursor } from '../cursor-cli.js';
@@ -12,8 +12,35 @@ import { Octokit } from '@octokit/rest';
const router = express.Router();
// Middleware to validate API key for external requests
/**
* Middleware to authenticate agent API requests.
*
* Supports two authentication modes:
* 1. Platform mode (VITE_IS_PLATFORM=true): For managed/hosted deployments where
* authentication is handled by an external proxy. Requests are trusted and
* the default user context is used.
*
* 2. API key mode (default): For self-hosted deployments where users authenticate
* via API keys created in the UI. Keys are validated against the local database.
*/
const validateExternalApiKey = (req, res, next) => {
// Platform mode: Authentication is handled externally (e.g., by a proxy layer).
// Trust the request and use the default user context.
if (process.env.VITE_IS_PLATFORM === 'true') {
try {
const user = userDb.getFirstUser();
if (!user) {
return res.status(500).json({ error: 'Platform mode: No user found in database' });
}
req.user = user;
return next();
} catch (error) {
console.error('Platform mode error:', error);
return res.status(500).json({ error: 'Platform mode: Failed to fetch user' });
}
}
// Self-hosted mode: Validate API key from header or query parameter
const apiKey = req.headers['x-api-key'] || req.query.apiKey;
if (!apiKey) {

View File

@@ -89,6 +89,7 @@ function AppContent() {
window.navigator.standalone ||
document.referrer.includes('android-app://');
setIsPWA(isStandalone);
document.addEventListener('touchstart', {});
// Add class to html and body for CSS targeting
if (isStandalone) {

View File

@@ -1,8 +1,8 @@
import React, { useEffect, useRef, useState, useCallback, useMemo } from 'react';
import { Terminal } from '@xterm/xterm';
import { FitAddon } from '@xterm/addon-fit';
import { ClipboardAddon } from '@xterm/addon-clipboard';
import { WebglAddon } from '@xterm/addon-webgl';
import { WebLinksAddon } from '@xterm/addon-web-links';
import '@xterm/xterm/css/xterm.css';
const xtermStyles = `
@@ -267,11 +267,12 @@ function Shell({ selectedProject, selectedSession, initialCommand, isPlainShell
});
fitAddon.current = new FitAddon();
const clipboardAddon = new ClipboardAddon();
const webglAddon = new WebglAddon();
const webLinksAddon = new WebLinksAddon();
terminal.current.loadAddon(fitAddon.current);
terminal.current.loadAddon(clipboardAddon);
terminal.current.loadAddon(webLinksAddon);
// Note: ClipboardAddon removed - we handle clipboard operations manually in attachCustomKeyEventHandler
try {
terminal.current.loadAddon(webglAddon);