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
@@ -9,6 +9,7 @@ import { useUIStore } from '@/stores/useUIStore';
|
||||
import { PROJECT_COLORS, PROJECT_ICONS, PROJECT_COLOR_MAP as COLOR_MAP, getProjectIconImageUrl } from '@/lib/projectMeta';
|
||||
import { RiCloseLine } from '@remixicon/react';
|
||||
import { WorktreeSectionContent } from '@/components/sections/openchamber/WorktreeSectionContent';
|
||||
import { ProjectActionsSection } from '@/components/sections/projects/ProjectActionsSection';
|
||||
|
||||
export const ProjectsPage: React.FC = () => {
|
||||
const projects = useProjectsStore((state) => state.projects);
|
||||
@@ -45,6 +46,13 @@ export const ProjectsPage: React.FC = () => {
|
||||
const [previewImageFailed, setPreviewImageFailed] = React.useState(false);
|
||||
const fileInputRef = React.useRef<HTMLInputElement | null>(null);
|
||||
|
||||
const selectedProjectRef = React.useMemo(() => {
|
||||
if (!selectedProject) {
|
||||
return null;
|
||||
}
|
||||
return { id: selectedProject.id, path: selectedProject.path };
|
||||
}, [selectedProject]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!selectedProject) {
|
||||
setName('');
|
||||
@@ -149,7 +157,6 @@ export const ProjectsPage: React.FC = () => {
|
||||
</ScrollableOverlay>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ScrollableOverlay keyboardAvoid outerClassName="h-full" className="w-full bg-background">
|
||||
<div className="mx-auto w-full max-w-4xl p-3 sm:p-6 sm:pt-8">
|
||||
@@ -370,6 +377,13 @@ export const ProjectsPage: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Worktree Group */}
|
||||
<div className="mb-8">
|
||||
<section className="px-2 pb-2 pt-0">
|
||||
{selectedProjectRef && <ProjectActionsSection projectRef={selectedProjectRef} />}
|
||||
</section>
|
||||
</div>
|
||||
|
||||
{/* Worktree Group */}
|
||||
<div className="mb-8">
|
||||
<div className="mb-1 px-1">
|
||||
@@ -378,7 +392,7 @@ export const ProjectsPage: React.FC = () => {
|
||||
</h3>
|
||||
</div>
|
||||
<section className="px-2 pb-2 pt-0">
|
||||
<WorktreeSectionContent projectRef={{ id: selectedProject.id, path: selectedProject.path }} />
|
||||
{selectedProjectRef && <WorktreeSectionContent projectRef={selectedProjectRef} />}
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user