feat: complete working-copies workspace-first cleanup
- Remove clone_mode/branch/new_branch from frontend create session flow. - Add workspace picker to CreateSessionForm; auto-create default workspace when repo selected. - Fix tool-starter.tsx and use-start-tool.ts createInstance signatures after API change. - Remove clone mode badge from SessionCard. - Delete stale backend unit tests referencing removed clone_mode schema fields. - Update OpenSpec working-copies tasks and mark change completed. - Regenerate project maps. Quality gates: npm run typecheck, npm run lint, npm test -- --run (82 passed), python3 -m py_compile on changed backend files.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
dir: apps/web
|
||||
|
||||
## role
|
||||
Browser-based web frontend providing the user-facing React application for code editing, terminal access, and routing functionality.
|
||||
Frontend web application providing a React-based UI with code editing, terminal, and routing capabilities for the "headquarter" project.
|
||||
## parent
|
||||
index: apps/.pi-map.index.md
|
||||
map: apps/.pi-map.md
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@ dir: apps/web
|
||||
index: apps/web/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Browser-based web frontend providing the user-facing React application for code editing, terminal access, and routing functionality.
|
||||
Frontend web application providing a React-based UI with code editing, terminal, and routing capabilities for the "headquarter" project.
|
||||
## files
|
||||
- .env.example | Template file defining example environment variables for frontend API and application URL configuration
|
||||
- .eslintrc.cjs | Configures ESLint for a TypeScript browser project with modern ECMAScript module support | dep: @typescript-eslint/parser, @typescript-eslint/eslint-plugin, eslint
|
||||
@@ -16,7 +16,7 @@ Browser-based web frontend providing the user-facing React application for code
|
||||
- tsconfig.json | TypeScript configuration file for a React project using Vite with modern ES2020 target and bundler module resolution | dep: typescript, react, vite
|
||||
- vite.config.ts | Configures Vite build tool for a React project with custom dev server port and Vitest test settings. | dep: vite, @vitejs/plugin-react
|
||||
## arch
|
||||
Modern React SPA built with Vite and TypeScript, containerized via multi-stage Docker/nginx deployment with client-side routing and optimized static asset delivery.
|
||||
Modern React SPA built with Vite and TypeScript, containerized via multi-stage Docker with nginx serving, featuring client-side routing, optimized static asset delivery, and development tooling (ESLint, Vitest).
|
||||
## tags
|
||||
react, eslint, vite, typescript, dom, application, nginx, web
|
||||
## symbols
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
dir: apps/web/src
|
||||
|
||||
## role
|
||||
Frontend web application entry point and core infrastructure for a React-based single-page application with authentication, routing, and domain type definitions.
|
||||
Frontend web application entry point and core infrastructure for a React single-page application with authentication, routing, and domain type definitions.
|
||||
## parent
|
||||
index: apps/web/.pi-map.index.md
|
||||
map: apps/web/.pi-map.md
|
||||
|
||||
@@ -4,13 +4,13 @@ dir: apps/web/src
|
||||
index: apps/web/src/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Frontend web application entry point and core infrastructure for a React-based single-page application with authentication, routing, and domain type definitions.
|
||||
Frontend web application entry point and core infrastructure for a React single-page application with authentication, routing, and domain type definitions.
|
||||
## files
|
||||
- main.tsx | Entry point that bootstraps a React SPA with routing, authentication, and session management context providers. | dep: react, react-dom/client, react-router-dom, ./router, ./state/auth, ./state/sessions, ./styles/tokens.css, ./styles/global.css, ./styles/utilities.css, ./styles/syntax-highlight.css, ./styles/pages/git-history.css, ./styles/pages/repo-workspace.css, ./styles/pages/projects.css, ./styles/pages/sessions.css, ./styles/pages/ssh-keys.css, ./styles/pages/workspace-detail.css, ./styles/pages/workspaces.css, react-dom, ./styles/*
|
||||
- router.tsx | Defines the React Router configuration for a web application with protected routes, nested layouts, and redirects. | exp: AppRouter | dep: react-router-dom, ./components/app-shell, ./components/protected-route, ./pages/DashboardPage, ./pages/PlaceholderPage, ./pages/ProfilePage, ./pages/ProjectsPage, ./pages/GitRepositoriesPage, ./pages/GitHistoryPage, ./pages/ProjectSettingsPage, ./pages/SettingsPage, ./pages/TerminalPage, ./pages/ToolWorkshopPage, ./pages/SshKeysPage, ./pages/ConfigProfilesPage, ./pages/SessionsPage, ./pages/WorkspacesPage, ./pages/WorkspaceDetailPage
|
||||
- types.ts | Defines TypeScript type definitions for user sessions, projects, repositories, and workspaces in an application. | exp: SessionUser, SessionPayload, Project, WorkspaceSummary, RepositorySummary, ProjectWithRepos
|
||||
## arch
|
||||
Layered React SPA architecture using context providers for cross-cutting concerns (auth/session), declarative routing with protected route guards and nested layouts, and centralized TypeScript type definitions for domain models.
|
||||
Layered React SPA architecture using context providers for cross-cutting concerns (auth/session), declarative routing with nested layouts and route guards, and centralized TypeScript type definitions for domain models.
|
||||
## tags
|
||||
pages, styles, css, router, react, session, dom, workspace
|
||||
## symbols
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
dir: apps/web/src/components
|
||||
|
||||
## role
|
||||
Provides reusable, foundational React UI components and utilities for the web application, including layout shell, data visualization, navigation guards, and user feedback systems.
|
||||
Provides foundational, reusable UI components and utilities for the web application, including layout shell, data states, icon system, code display, routing guards, and toast notification rules.
|
||||
## parent
|
||||
index: apps/web/src/.pi-map.index.md
|
||||
map: apps/web/src/.pi-map.md
|
||||
|
||||
@@ -4,7 +4,7 @@ dir: apps/web/src/components
|
||||
index: apps/web/src/components/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Provides reusable, foundational React UI components and utilities for the web application, including layout shell, data visualization, navigation guards, and user feedback systems.
|
||||
Provides foundational, reusable UI components and utilities for the web application, including layout shell, data states, icon system, code display, routing guards, and toast notification rules.
|
||||
## files
|
||||
- app-shell.tsx | Renders the main application shell layout with navigation, session management, and responsive mobile/desktop views for a React Router-based app. | exp: AppShell | dep: react-router-dom, ../api/sessions, ../hooks/use-theme, ../state/auth, ../state/sessions, ../hooks/use-mobile-viewport, ../state/events, ../state/toast, ../state/notifications, ../state/session-operations, ./features/notification/event-toast-bridge, ./features/notification/notification-center, ./features/session/session-progress-panel, ./icon, ./features/mobile/mobile-nav, ./features/tool/start-tool-fab, ../utils/icons
|
||||
- code-editor.tsx | A React component that renders a syntax-highlighted code editor with line numbers using react-simple-code-editor. | exp: CodeEditor | dep: react, react-simple-code-editor, ../utils/language
|
||||
@@ -16,7 +16,7 @@ Provides reusable, foundational React UI components and utilities for the web ap
|
||||
- toast-rules.test.ts | Unit tests for mapping instance events to toast notification categories and severities | dep: vitest, ./toast-rules, ../types/events
|
||||
- toast-rules.ts | Maps instance events to toast notifications with deduplication logic to prevent spam | exp: func:mapEventToCategory(event: InstanceEventPayload) → string, call:event.event.startsWith, func:mapEventToSeverity(event: InstanceEventPayload) → "info" | "warning" | "error" | "success", func:handleEventToast(event: InstanceEventPayload) → void, call:shouldShowToast, call:toast.info, call:toast.success, call:toast.warning, call:toast.error, func:clearToastDedup() → void, call:lastToastTime.clear | dep: ../state/toast, ../types/events, toast state module, InstanceEventPayload type
|
||||
## arch
|
||||
Component-based architecture with functional React patterns, composition of specialized sub-components (icon, editor, syntax highlighter), separation of concerns via dedicated state-management components (data states, protected routes), and utility modules with pure logic for cross-cutting concerns (toast rules with deduplication).
|
||||
Follows a component-based React architecture with separation of concerns between presentational components (icon, data-states, code-editor), layout/app-shell orchestration, auth-guarded routing (protected-route), and domain-specific utility modules (toast-rules) with colocated unit tests.
|
||||
## tags
|
||||
toast, state, react, icon, code, event, editor, protected
|
||||
## symbols
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
dir: apps/web/src/components/features
|
||||
|
||||
## role
|
||||
Contains reusable React components that implement specific product features and business logic for the web application.
|
||||
Contains specialized UI components for major feature areas of the web application, organizing components by business domain rather than by atomic design level.
|
||||
## parent
|
||||
index: apps/web/src/components/.pi-map.index.md
|
||||
map: apps/web/src/components/.pi-map.md
|
||||
|
||||
@@ -4,10 +4,10 @@ dir: apps/web/src/components/features
|
||||
index: apps/web/src/components/features/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Contains reusable React components that implement specific product features and business logic for the web application.
|
||||
Contains specialized UI components for major feature areas of the web application, organizing components by business domain rather than by atomic design level.
|
||||
## files
|
||||
## arch
|
||||
Feature-based component organization with domain-specific UI building blocks, likely composed of atomic design elements (from components/ui) and consumed by page-level routes.
|
||||
Feature-based colocation pattern where components are grouped by product functionality (e.g., checkout, dashboard, settings) rather than by component type, typically combining multiple atomic components with domain-specific logic and data fetching.
|
||||
## tags
|
||||
-
|
||||
## symbols
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
dir: apps/web/src/components/features/session
|
||||
|
||||
## role
|
||||
Provides UI components for managing development environment sessions including creation, listing, monitoring progress, and interacting with individual sessions.
|
||||
Provides UI components for managing development sessions including creation, listing, monitoring progress, and interacting with individual sessions.
|
||||
## parent
|
||||
index: apps/web/src/components/features/.pi-map.index.md
|
||||
map: apps/web/src/components/features/.pi-map.md
|
||||
|
||||
@@ -4,16 +4,16 @@ dir: apps/web/src/components/features/session
|
||||
index: apps/web/src/components/features/session/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Provides UI components for managing development environment sessions including creation, listing, monitoring progress, and interacting with individual sessions.
|
||||
Provides UI components for managing development sessions including creation, listing, monitoring progress, and interacting with individual sessions.
|
||||
## files
|
||||
- create-session-form.tsx | React form component for creating development sessions with configurable project, repository, tool type, branch, SSH keys, and config profile options | exp: CreateSessionForm | dep: react, ../../icon, ../../../api/sessions, ../../../types, ../../../api/git-repositories, ../../../api/tool-types, ../../../api/ssh-keys, ../../../api/config-profiles, icon component, sessions API, git-repositories API, ssh-keys API, config-profiles API, tool-types API, types
|
||||
- session-card.tsx | Renders a React card component displaying session information with status badges, inline editing, action buttons, and responsive mobile/desktop layouts. | exp: SessionCardProps, func:SessionCard({ session, onOpen, onStart, onStop, onDelete, onRecreateTunnel, onRename, isBusy = false, tunnelHealth = null, }: SessionCardProps), call:useState, call:useRef, call:useMobileViewport, call:session.tool_type_interfaces?.includes, call:[ "running", "building", "starting", "probing", "pending", "unhealthy", ].includes, call:useEffect, call:optionsRef.current.contains, call:setOptionsOpen, call:document.addEventListener, call:document.removeEventListener, call:window.confirm, call:onDelete, call:setEditName, call:onRename, call:setIsEditingName, call:editName.trim, call:onOpen, call:new Date(session.created_at).toLocaleString, call:setShowActionSheet, call:onStart, call:onStop, call:onRecreateTunnel | dep: react, ../../../api/sessions, ../../icon, ../../../hooks/use-mobile-viewport, ../mobile/mobile-action-sheet, icon, use-mobile-viewport, mobile-action-sheet, sessions api types
|
||||
- create-session-form.tsx | A React form component for creating and starting a new development session with configurable project, repository, workspace, tool type, config profile, and SSH key options. | exp: CreateSessionForm | dep: react, ../../icon, ../../../api/sessions, ../../../types, ../../../api/git-repositories, ../../../api/tool-types, ../../../api/ssh-keys, ../../../api/config-profiles, ../../../api/workspaces, ../../../types/workspace, icon, sessions API, git-repositories API, tool-types API, ssh-keys API, config-profiles API, workspaces API, types
|
||||
- session-card.tsx | Renders a card component displaying session information with status badges, inline rename editing, action buttons, and responsive mobile/desktop layouts including a dropdown options menu and mobile action sheet. | exp: SessionCardProps, func:SessionCard({ session, onOpen, onStart, onStop, onDelete, onRecreateTunnel, onRename, isBusy = false, tunnelHealth = null, }: SessionCardProps), call:useState, call:useRef, call:useMobileViewport, call:session.tool_type_interfaces?.includes, call:[ "running", "building", "starting", "probing", "pending", "unhealthy", ].includes, call:useEffect, call:optionsRef.current.contains, call:setOptionsOpen, call:document.addEventListener, call:document.removeEventListener, call:window.confirm, call:onDelete, call:setEditName, call:onRename, call:setIsEditingName, call:editName.trim, call:onOpen, call:new Date(session.created_at).toLocaleString, call:setShowActionSheet, call:onStart, call:onStop, call:onRecreateTunnel | dep: react, ../../../api/sessions, ../../icon, ../../../hooks/use-mobile-viewport, ../mobile/mobile-action-sheet
|
||||
- session-list.tsx | Renders a list of sessions grouped by active/recent status or as a flat grid, delegating to SessionCard for individual session display. | exp: SessionListProps, func:SessionList({ sessions, onOpen, onStart, onStop, onDelete, onRecreateTunnel, onRename, actionBusyId = null, tunnelHealth = {}, showGrouping = true, activeTitle = "Active Sessions", recentTitle = "Recent Sessions", maxRecent = 5, emptyMessage = "No sessions", }: SessionListProps), call:sessions.filter, call:activeStatuses.includes, call:sessions .filter((s) => recentStatuses.includes(s.status)) .slice, call:recentStatuses.includes, call:sessions.map, call:activeSessions.map, call:recentSessions.map | dep: ../../../api/sessions, ./session-card, Session, SessionCard, InstanceHealth
|
||||
- session-progress-panel.tsx | Renders a panel displaying active and recently completed session operations with step-by-step progress indicators and dismissible notifications. | exp: func:SessionProgressPanel(), call:useSessionOperations, call:useEventContext, call:useEffect, call:updateOperationFromEvent, call:operations.filter, call:Date.now, call:visibleOperations.map, call:dismissOperation | dep: react, ../../../state/session-operations, ../../../state/events, ../../icon, useSessionOperations, useEventContext, Icon
|
||||
## arch
|
||||
Feature-based component composition with presentational components following a container/presenter pattern, using status-driven conditional rendering and responsive layout adaptations.
|
||||
React component composition with feature-specific grouping, responsive design patterns (mobile/desktop layouts), and status-driven conditional rendering with delegated sub-components.
|
||||
## tags
|
||||
session, call:use, call:on, card, mobile, call:set, event, api
|
||||
session, call:use, call:on, api, card, call:set, event, mobile
|
||||
## symbols
|
||||
- SessionCard
|
||||
- SessionList
|
||||
|
||||
@@ -13,6 +13,8 @@ import {
|
||||
listConfigProfiles,
|
||||
type ConfigProfile,
|
||||
} from "../../../api/config-profiles";
|
||||
import { listWorkspaces, createWorkspace } from "../../../api/workspaces";
|
||||
import type { Workspace } from "../../../types/workspace";
|
||||
|
||||
interface CreateSessionFormProps {
|
||||
projects: Project[];
|
||||
@@ -54,6 +56,10 @@ export const CreateSessionForm = ({
|
||||
const [selectedConfigProfile, setSelectedConfigProfile] = useState("");
|
||||
const [selectedSshKeyIds, setSelectedSshKeyIds] = useState<string[]>([]);
|
||||
|
||||
const [workspaces, setWorkspaces] = useState<Workspace[]>([]);
|
||||
const [selectedWorkspaceId, setSelectedWorkspaceId] = useState("");
|
||||
const [isLoadingWorkspaces, setIsLoadingWorkspaces] = useState(false);
|
||||
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
@@ -94,6 +100,50 @@ export const CreateSessionForm = ({
|
||||
void loadProfiles();
|
||||
}, [selectedToolType, selectedProject, fixedProjectId]);
|
||||
|
||||
// Load workspaces when repository is selected
|
||||
useEffect(() => {
|
||||
const projectId = fixedProjectId || selectedProject;
|
||||
const repoId = fixedRepoId || selectedRepo;
|
||||
if (!projectId || !repoId) {
|
||||
setWorkspaces([]);
|
||||
setSelectedWorkspaceId("");
|
||||
return;
|
||||
}
|
||||
const loadWorkspaces = async () => {
|
||||
setIsLoadingWorkspaces(true);
|
||||
try {
|
||||
const data = await listWorkspaces(projectId, repoId);
|
||||
setWorkspaces(data);
|
||||
if (data.length > 0) {
|
||||
setSelectedWorkspaceId(data[0].id);
|
||||
} else {
|
||||
// Auto-create a default workspace so the user can start a tool
|
||||
const workspace = await createWorkspace(projectId, repoId, {
|
||||
name: "default",
|
||||
branch: "main",
|
||||
});
|
||||
setWorkspaces([workspace]);
|
||||
setSelectedWorkspaceId(workspace.id);
|
||||
}
|
||||
} catch (err) {
|
||||
setError(
|
||||
err instanceof Error ? err.message : "Failed to load workspaces",
|
||||
);
|
||||
setWorkspaces([]);
|
||||
setSelectedWorkspaceId("");
|
||||
} finally {
|
||||
setIsLoadingWorkspaces(false);
|
||||
}
|
||||
};
|
||||
void loadWorkspaces();
|
||||
}, [
|
||||
fixedProjectId,
|
||||
selectedProject,
|
||||
fixedRepoId,
|
||||
selectedRepo,
|
||||
repositories,
|
||||
]);
|
||||
|
||||
// Filter repositories by selected project
|
||||
const availableRepos = selectedProject
|
||||
? repositories.filter((r) => r.project_id === selectedProject)
|
||||
@@ -106,6 +156,8 @@ export const CreateSessionForm = ({
|
||||
setDisplayName("");
|
||||
setSelectedSshKeyIds([]);
|
||||
setSelectedConfigProfile("");
|
||||
setWorkspaces([]);
|
||||
setSelectedWorkspaceId("");
|
||||
};
|
||||
|
||||
const handleSubmit = async (event: React.FormEvent) => {
|
||||
@@ -123,12 +175,19 @@ export const CreateSessionForm = ({
|
||||
setIsSubmitting(true);
|
||||
|
||||
try {
|
||||
const workspaceId = selectedWorkspaceId || undefined;
|
||||
if (!workspaceId) {
|
||||
setError("No workspace available for the selected repository");
|
||||
setIsSubmitting(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const instance = await createInstance(
|
||||
projectId,
|
||||
repoId,
|
||||
selectedToolType,
|
||||
displayName || undefined,
|
||||
undefined,
|
||||
workspaceId,
|
||||
selectedConfigProfile || undefined,
|
||||
selectedSshKeyIds.length > 0 ? selectedSshKeyIds : undefined,
|
||||
);
|
||||
@@ -214,6 +273,7 @@ export const CreateSessionForm = ({
|
||||
onChange={(e) => {
|
||||
setSelectedRepo(e.target.value);
|
||||
setSelectedToolType("");
|
||||
setSelectedWorkspaceId("");
|
||||
}}
|
||||
disabled={!hasProject || isSubmitting}
|
||||
>
|
||||
@@ -228,6 +288,30 @@ export const CreateSessionForm = ({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Workspace */}
|
||||
{hasRepo && (
|
||||
<div className="form-field">
|
||||
<label>Workspace</label>
|
||||
{isLoadingWorkspaces ? (
|
||||
<span className="muted">Loading workspaces...</span>
|
||||
) : workspaces.length === 0 ? (
|
||||
<span className="muted">No workspace available</span>
|
||||
) : (
|
||||
<select
|
||||
value={selectedWorkspaceId}
|
||||
onChange={(e) => setSelectedWorkspaceId(e.target.value)}
|
||||
disabled={!hasRepo || isSubmitting || isLoadingWorkspaces}
|
||||
>
|
||||
{workspaces.map((w) => (
|
||||
<option key={w.id} value={w.id}>
|
||||
{w.name} ({w.branch})
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Tool Type */}
|
||||
{hasRepo && (
|
||||
<div className="form-field">
|
||||
|
||||
@@ -176,14 +176,6 @@ export function SessionCard({
|
||||
)}{" "}
|
||||
· {session.tool_type_name}
|
||||
</p>
|
||||
{session.clone_mode && (
|
||||
<p className="muted session-card-meta">
|
||||
<Icon name="branch" size="sm" />
|
||||
{session.clone_mode === "clone"
|
||||
? `Clone${session.branch ? ` (${session.branch})` : ""}`
|
||||
: "Mount"}
|
||||
</p>
|
||||
)}
|
||||
{session.url && (
|
||||
<p className="session-card-url">
|
||||
<button
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
dir: apps/web/src/components/features/tool
|
||||
|
||||
## role
|
||||
Provides UI components for managing container-based development tools, including instance lifecycle operations, manifest editing, and workspace-integrated tool launching.
|
||||
Provides UI components for managing containerized development tools, including instance lifecycle operations, manifest editing, and workspace-integrated tool launching.
|
||||
## parent
|
||||
index: apps/web/src/components/features/.pi-map.index.md
|
||||
map: apps/web/src/components/features/.pi-map.md
|
||||
|
||||
@@ -4,16 +4,16 @@ dir: apps/web/src/components/features/tool
|
||||
index: apps/web/src/components/features/tool/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Provides UI components for managing container-based development tools, including instance lifecycle operations, manifest editing, and workspace-integrated tool launching.
|
||||
Provides UI components for managing containerized development tools, including instance lifecycle operations, manifest editing, and workspace-integrated tool launching.
|
||||
## files
|
||||
- instance-list.tsx | Displays and manages a list of tool instances with CRUD operations, real-time status updates, and configuration profile selection. | exp: InstanceList | dep: react, react-router-dom, ../../icon, ../../../api/sessions, ../../../api/tool-types, ../session/create-session-form, ../../../api/config-profiles, ../../../api/ssh-keys, ../../../state/events, ../../../state/sessions, icon, api/sessions, api/tool-types, api/config-profiles, api/ssh-keys, state/events, state/sessions
|
||||
- manifest-editor.tsx | A React component that provides a form-based UI for editing container tool definition manifests with fields for base images, packages, user config, environment variables, scripts, mounts, and runtime settings, including compilation preview functionality. | exp: ManifestEditor | dep: react, ../../icon, ../../../utils/errors, ../../../api/tool-definitions, icon, errors, tool-definitions
|
||||
- start-tool-fab.tsx | A floating action button component that opens a modal to select a workspace and start a tool. | exp: func:StartToolFAB(), call:useState, call:setOpen, call:setWorkspacesLoading, call:listAllWorkspaces, call:setWorkspaces, call:setSelectedWorkspace, call:e.stopPropagation, call:workspaces.find, call:workspaces.map | dep: react, ../../icon, ./tool-starter, ../../../types/workspace, ../../../api/workspaces, icon, tool-starter, workspaces api, workspace types
|
||||
- start-tool-modal.tsx | Renders a modal dialog for selecting a tool type and optional config profile to start on a workspace. | exp: StartToolModalProps, func:StartToolModal({ workspace, onClose, onStart, }: StartToolModalProps), call:useState, call:useAsyncData, call:e.preventDefault, call:setError, call:setSubmitting, call:onStart, call:onClose, call:e.stopPropagation, call:setToolTypeId, call:toolTypes?.map, call:setConfigProfileId | dep: react, ../../icon, ../../../api/tool-types, ../../../hooks/use-async-data, ../../../types/workspace, icon, tool-types, use-async-data, workspace
|
||||
- tool-starter.tsx | React component that provides a workspace-first form for starting a new tool instance, fetching tool types, config profiles, and SSH keys dynamically. | exp: ToolStarterProps, func:ToolStarter({ workspace, onStarted, onCancel, }: ToolStarterProps), call:useSessions, call:useSessionOperations, call:useState, call:useEffect, call:listToolTypes, call:setToolTypes, call:setToolTypesError, call:setToolTypesLoading, call:load, call:setProfiles, call:setSelectedProfileId, call:setProfilesLoading, call:listConfigProfiles, call:data.find, call:listSSHKeys, call:setSshKeys, call:setSelectedSshKeyIds, call:console.error, call:setSshKeysLoading, call:sshKeys.find, call:useCallback, call:setError, call:setStarting, call:createInstance, call:displayName.trim, call:startInstance, call:addOrUpdateSession, call:startOperation, call:onStarted, call:setSelectedToolTypeId, call:toolTypes.find, call:setDisplayName, call:toolTypes.map, call:setNameEdited, call:profiles.map, call:sshKeys.map, call:selectedSshKeyIds.includes, call:prev.filter | dep: react, ../../icon, ../../../api/tool-types, ../../../api/config-profiles, ../../../api/ssh-keys, ../../../state/sessions, ../../../state/session-operations, ../../../types/workspace, ../../../api/sessions, icon, tool-types, config-profiles, ssh-keys, sessions, session-operations, workspace
|
||||
- tool-starter.tsx | A React component that provides a workspace-first UI for selecting tool types, config profiles, and SSH keys to create and start a new tool instance/session. | exp: ToolStarterProps, func:ToolStarter({ workspace, onStarted, onCancel, }: ToolStarterProps), call:useSessions, call:useSessionOperations, call:useState, call:useEffect, call:listToolTypes, call:setToolTypes, call:setToolTypesError, call:setToolTypesLoading, call:load, call:setProfiles, call:setSelectedProfileId, call:setProfilesLoading, call:listConfigProfiles, call:data.find, call:listSSHKeys, call:setSshKeys, call:setSelectedSshKeyIds, call:console.error, call:setSshKeysLoading, call:sshKeys.find, call:useCallback, call:setError, call:setStarting, call:createInstance, call:displayName.trim, call:startInstance, call:addOrUpdateSession, call:startOperation, call:onStarted, call:setSelectedToolTypeId, call:toolTypes.find, call:setDisplayName, call:toolTypes.map, call:setNameEdited, call:profiles.map, call:sshKeys.map, call:selectedSshKeyIds.includes, call:prev.filter | dep: react, ../../icon, ../../../api/tool-types, ../../../api/config-profiles, ../../../api/ssh-keys, ../../../state/sessions, ../../../state/session-operations, ../../../types/workspace, ../../../api/sessions, icon, tool-types, config-profiles, ssh-keys, sessions, session-operations, workspace
|
||||
- tools-bottom-sheet.tsx | Renders a mobile bottom sheet navigation menu for tools with active route highlighting | exp: ToolsBottomSheet | dep: react-router-dom, ../../icon, icon
|
||||
## arch
|
||||
Feature-based component architecture with form-driven modals, real-time status integration, and responsive mobile/desktop patterns (bottom sheets vs modals)
|
||||
Feature-based component composition with modal/bottom-sheet navigation patterns, real-time status integration, and form-driven configuration management with preview capabilities.
|
||||
## tags
|
||||
tool, call:set, types, call:use, api, start, ssh, icon
|
||||
## symbols
|
||||
|
||||
@@ -131,12 +131,9 @@ export function ToolStarter({
|
||||
workspace.repo_id,
|
||||
selectedToolTypeId,
|
||||
displayName.trim() || undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
workspace.id,
|
||||
selectedProfileId || undefined,
|
||||
selectedSshKeyIds.length > 0 ? selectedSshKeyIds : undefined,
|
||||
workspace.id,
|
||||
);
|
||||
await startInstance(
|
||||
workspace.project_id,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
dir: apps/web/src/hooks
|
||||
|
||||
## role
|
||||
Provides a comprehensive collection of custom React hooks that encapsulate reusable stateful logic, side effects, and API interactions for the web application's UI, data management, and domain-specific operations.
|
||||
Provides reusable React custom hooks that encapsulate UI state management, side effects, API integrations, and domain-specific logic for the web application frontend.
|
||||
## parent
|
||||
index: apps/web/src/.pi-map.index.md
|
||||
map: apps/web/src/.pi-map.md
|
||||
|
||||
@@ -4,7 +4,7 @@ dir: apps/web/src/hooks
|
||||
index: apps/web/src/hooks/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Provides a comprehensive collection of custom React hooks that encapsulate reusable stateful logic, side effects, and API interactions for the web application's UI, data management, and domain-specific operations.
|
||||
Provides reusable React custom hooks that encapsulate UI state management, side effects, API integrations, and domain-specific logic for the web application frontend.
|
||||
## files
|
||||
- use-async-data.ts | A custom React hook that manages asynchronous data fetching with loading, error, and ready states, plus a manual reload capability. | exp: func:useAsyncData(fetcher: () => Promise<T>, deps: React.DependencyList) → UseAsyncDataResult<T>, call:useState, call:useCallback, call:setStatus, call:setError, call:fetcher, call:setData, call:load, call:useEffect | dep: react
|
||||
- use-auto-hide.ts | A React custom hook that automatically hides an element after a specified timeout and provides manual controls for showing, hiding, and toggling visibility. | exp: func:useAutoHide(options: AutoHideOptions), call:useState, call:useRef, call:Date.now, call:useCallback, call:setIsVisible, call:clearTimeout, call:setTimeout, call:hide, call:show, call:useEffect | dep: react
|
||||
@@ -20,7 +20,7 @@ Provides a comprehensive collection of custom React hooks that encapsulate reusa
|
||||
- use-repo-workspace.ts | A React custom hook that manages workspace state for a repository-based project, including loading project data, repositories, branches, git status, and tool types while synchronizing selection state with URL search parameters. | exp: Project, useRepoWorkspace | dep: react, react-router-dom, ../api/client, ../api/git-repositories, ../api/tool-types
|
||||
- use-special-keys.ts | Maps special keys and modifier+character combinations to ANSI escape sequences for terminal input simulation. | exp: SpecialKey, ModifierKey, func:getSequenceWithModifier(key: SpecialKey, activeModifier: ModifierKey | null) → { sequence: string; clearModifier: boolean } | null, call:char.toLowerCase, func:applyModifierToChar(char: string, modifier: ModifierKey) → string | null, call:char.toLowerCase
|
||||
- use-ssh-keys.ts | A React custom hook that manages SSH key operations including listing, generating, deleting, signing payloads, and verifying signatures. | exp: useSSHKeys | dep: react, ../api/ssh-keys, ./use-async-data
|
||||
- use-start-tool.ts | React hook that manages the state and API calls for creating and starting a tool instance on a workspace | exp: UseStartToolResult, func:useStartTool() → UseStartToolResult, call:useState, call:useCallback, call:setStarting, call:setError, call:createInstance, call:startInstance | dep: react, ../api/sessions, ../types/workspace
|
||||
- use-start-tool.ts | React hook for managing the state and API calls to create and start a tool instance on a workspace. | exp: UseStartToolResult, func:useStartTool() → UseStartToolResult, call:useState, call:useCallback, call:setStarting, call:setError, call:createInstance, call:startInstance | dep: react, ../api/sessions, ../types/workspace
|
||||
- use-terminal-page.ts | Manages terminal page state including sessions, keyboard shortcuts, fullscreen mode, mobile viewport handling, and terminal lifecycle operations. | exp: useTerminalPage | dep: react, react-router-dom, ../components/features/terminal/terminal, ../components/features/terminal/terminal-session-tabs, ./use-mobile-viewport, ./use-auto-hide, ./use-virtual-keyboard, ./use-terminal-sessions, ../api/terminal, ./use-special-keys, use-mobile-viewport, use-auto-hide, use-virtual-keyboard, use-terminal-sessions, terminal, terminal-session-tabs, api/terminal, api/sessions, use-special-keys
|
||||
- use-terminal-sessions.ts | React custom hook that manages terminal session state (CRUD operations, active session tracking) for a given instance | exp: UseTerminalSessionsResult, func:useTerminalSessions(instanceId: string) → UseTerminalSessionsResult, call:useState, call:useCallback, call:setLoading, call:setError, call:listTerminalSessions, call:setSessions, call:setActiveSessionId, call:createTerminalSession, call:closeTerminalSession, call:prev.filter, call:renameTerminalSession, call:prev.map, call:resetTerminalSession, call:loadSessions, call:useEffect | dep: react, ../api/terminal
|
||||
- use-theme.ts | React hook that fetches user theme preference on mount and applies it to the document root element via data-theme attribute | exp: func:useTheme(), call:useEffect, call:getUserConfig, call:document.documentElement.removeAttribute, call:document.documentElement.setAttribute | dep: react, ../api/settings
|
||||
@@ -32,7 +32,7 @@ Provides a comprehensive collection of custom React hooks that encapsulate reusa
|
||||
- use-workspace-instances.ts | Custom React hook for managing workspace instances with CRUD operations, loading states, and error handling. | exp: UseWorkspaceInstancesResult, func:useWorkspaceInstances(workspaceId: string) → UseWorkspaceInstancesResult, call:useState, call:useCallback, call:setLoading, call:setError, call:listWorkspaceInstances, call:setInstances, call:createWorkspaceInstance, call:refresh, call:useEffect | dep: react, ../api/workspace-instances, ../api/sessions
|
||||
- use-workspaces.ts | Custom React hook that fetches and manages workspace data with loading and error states. | exp: UseWorkspacesResult, func:useWorkspaces(projectId: string, repoId: string) → UseWorkspacesResult, call:useState, call:useCallback, call:setLoading, call:setError, call:listWorkspaces, call:listAllWorkspaces, call:setWorkspaces, call:useEffect, call:refresh | dep: react, ../api/workspaces, ../types/workspace
|
||||
## arch
|
||||
Follows the React Hooks pattern with custom hooks as the primary abstraction—each hook typically combines useState/useEffect/useCallback to manage local state, API calls, and side effects; many hooks integrate with TanStack Query/SWR-like patterns for server state (loading/error/reload), use context providers (e.g., NotificationProvider), and synchronize with URL search params; complex hooks compose simpler ones (e.g., use-terminal-page composes use-mobile-viewport, use-auto-hide) and use reducer-like state management for multi-faceted domain operations (CRUD, drag-and-drop, form handling).
|
||||
Layered utility hooks following React composition patterns, with separation between generic UI behavior hooks (async data, auto-hide, viewport, theme), infrastructure hooks (SSE, terminal, keyboard), and domain-specific data/operation hooks (workspace, git, SSH, projects, instances) that wrap API calls with loading/error states and optimistic updates.
|
||||
## tags
|
||||
call:set, call:use, workspace, react, state, terminal, api, git
|
||||
## symbols
|
||||
|
||||
@@ -35,12 +35,9 @@ export function useStartTool(): UseStartToolResult {
|
||||
workspace.repo_id,
|
||||
toolTypeId,
|
||||
displayName || workspace.name,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
workspace.id,
|
||||
configProfileId,
|
||||
[],
|
||||
workspace.id,
|
||||
);
|
||||
await startInstance(
|
||||
workspace.project_id,
|
||||
|
||||
Reference in New Issue
Block a user