Project actions: run commands from header on web + mobile, with SSH-forward URL opening (#542)
* feat: add project actions in header with reliable terminal run flow - Add per-project Actions settings with icons, platform filters, and default action - Run/stop actions from header using terminal tabs, including Ctrl+C then force-kill fallback - Improve terminal UX with stable selection, resize handling, and smarter URL auto-open for localhost ports * feat: add project actions UI with refined header dropdown behavior * feat: add parent-session back button in chat * fix: make web and desktop dev modes reliable and conflict-free - Separate desktop and web dev ports to avoid collisions - Add robust process-tree shutdown so Ctrl+C cleans sidecars - Add true web HMR mode and keep service worker out of dev * fix: linux safe scripts for dev * feat: run project actions on web and add desktop SSH forward URL opening * feat: add mobile project actions button with terminal tabs and tighter tab UI * revert: remove experimental mobile terminal selection UI * feat: show Add action button in header when empty * fix: make retry countdown human-readable in status row * fix: prevent nav rail actions from firing through overlays
This commit is contained in:
committed by
GitHub
parent
d948aa5557
commit
95c71789c4
@@ -11528,6 +11528,13 @@ async function main(options = {}) {
|
||||
const terminalSessions = new Map();
|
||||
const MAX_TERMINAL_SESSIONS = 20;
|
||||
const TERMINAL_IDLE_TIMEOUT = 30 * 60 * 1000;
|
||||
const sanitizeTerminalEnv = (env) => {
|
||||
const next = { ...env };
|
||||
delete next.BASH_XTRACEFD;
|
||||
delete next.BASH_ENV;
|
||||
delete next.ENV;
|
||||
return next;
|
||||
};
|
||||
const terminalInputCapabilities = {
|
||||
input: {
|
||||
preferred: 'ws',
|
||||
@@ -11751,7 +11758,7 @@ async function main(options = {}) {
|
||||
Math.random().toString(36).substring(2, 15);
|
||||
|
||||
const envPath = buildAugmentedPath();
|
||||
const resolvedEnv = { ...process.env, PATH: envPath };
|
||||
const resolvedEnv = sanitizeTerminalEnv({ ...process.env, PATH: envPath });
|
||||
|
||||
const pty = await getPtyProvider();
|
||||
const { ptyProcess, shell } = spawnTerminalPtyWithFallback(pty, {
|
||||
@@ -11965,7 +11972,7 @@ async function main(options = {}) {
|
||||
Math.random().toString(36).substring(2, 15);
|
||||
|
||||
const envPath = buildAugmentedPath();
|
||||
const resolvedEnv = { ...process.env, PATH: envPath };
|
||||
const resolvedEnv = sanitizeTerminalEnv({ ...process.env, PATH: envPath });
|
||||
|
||||
const pty = await getPtyProvider();
|
||||
const { ptyProcess, shell } = spawnTerminalPtyWithFallback(pty, {
|
||||
|
||||
+11
-15
@@ -13,20 +13,16 @@ declare global {
|
||||
|
||||
window.__OPENCHAMBER_RUNTIME_APIS__ = createWebAPIs();
|
||||
|
||||
registerSW({
|
||||
onRegistered(registration: ServiceWorkerRegistration | undefined) {
|
||||
if (!registration) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Periodic update check (best-effort)
|
||||
setInterval(() => {
|
||||
void registration.update();
|
||||
}, 60 * 60 * 1000);
|
||||
},
|
||||
onRegisterError(error: unknown) {
|
||||
console.warn('[PWA] service worker registration failed:', error);
|
||||
},
|
||||
});
|
||||
if (import.meta.env.PROD) {
|
||||
registerSW({
|
||||
onRegisterError(error: unknown) {
|
||||
console.warn('[PWA] service worker registration failed:', error);
|
||||
},
|
||||
});
|
||||
} else if ('serviceWorker' in navigator) {
|
||||
void navigator.serviceWorker.getRegistrations()
|
||||
.then((registrations) => Promise.all(registrations.map((registration) => registration.unregister())))
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
import('@openchamber/ui/main');
|
||||
|
||||
@@ -8,6 +8,7 @@ import { themeStoragePlugin } from '../../vite-theme-plugin';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const packageJson = JSON.parse(readFileSync(path.resolve(__dirname, 'package.json'), 'utf-8'));
|
||||
const pwaDevEnabled = process.env.OPENCHAMBER_DISABLE_PWA_DEV !== '1';
|
||||
const reactScanToggle = (process.env.VITE_ENABLE_REACT_SCAN ?? '').toLowerCase();
|
||||
const enableReactScan = reactScanToggle === '1' || reactScanToggle === 'true' || reactScanToggle === 'on' || reactScanToggle === 'yes';
|
||||
|
||||
@@ -53,7 +54,7 @@ export default defineConfig({
|
||||
injectionPoint: undefined,
|
||||
},
|
||||
devOptions: {
|
||||
enabled: true,
|
||||
enabled: pwaDevEnabled,
|
||||
type: 'module',
|
||||
},
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user