Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 346b32236a | |||
| 8f7f682a92 | |||
| 2ece7074f6 | |||
| c7ab2de25e | |||
| c9b0259993 | |||
| 1f2c3dbe2a | |||
| d247e44985 | |||
| d60dec9d62 | |||
| 4913cc7297 | |||
| 86360661e9 | |||
| 1d09193652 |
+1
-1
@@ -16,7 +16,7 @@ dir: .
|
|||||||
Trust boundary: index routes, map orients, source decides.
|
Trust boundary: index routes, map orients, source decides.
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Infrastructure and deployment configuration for a self-hosted project management and git repository platform with OAuth2 authentication.
|
Infrastructure and deployment configuration package for a self-hosted project management platform with OAuth2 authentication, providing containerized orchestration, environment templates, and development tooling.
|
||||||
## parent
|
## parent
|
||||||
-
|
-
|
||||||
## children
|
## children
|
||||||
|
|||||||
+2
-2
@@ -18,7 +18,7 @@ index: ./.pi-map.index.md
|
|||||||
Trust boundary: index routes, map orients, source decides.
|
Trust boundary: index routes, map orients, source decides.
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Infrastructure and deployment configuration for a self-hosted project management and git repository platform with OAuth2 authentication.
|
Infrastructure and deployment configuration package for a self-hosted project management platform with OAuth2 authentication, providing containerized orchestration, environment templates, and development tooling.
|
||||||
## files
|
## files
|
||||||
- .env.example | Provides a template of environment variables for configuring a Headquarter application with PostgreSQL, Redis, Authentik SSO, and Docker/Traefik deployment
|
- .env.example | Provides a template of environment variables for configuring a Headquarter application with PostgreSQL, Redis, Authentik SSO, and Docker/Traefik deployment
|
||||||
- .gitignore | Specifies files and directories for Git to ignore across a multi-language project with Python, Node, and custom tooling | dep: Git
|
- .gitignore | Specifies files and directories for Git to ignore across a multi-language project with Python, Node, and custom tooling | dep: Git
|
||||||
@@ -31,7 +31,7 @@ Infrastructure and deployment configuration for a self-hosted project management
|
|||||||
- progress.md | Tracks completed and remaining tasks for a backend-frontend code refactoring project organized in 7 phases
|
- progress.md | Tracks completed and remaining tasks for a backend-frontend code refactoring project organized in 7 phases
|
||||||
- swap-pane | Empty file with no functionality
|
- swap-pane | Empty file with no functionality
|
||||||
## arch
|
## arch
|
||||||
Containerized microservices architecture using Docker Compose with PostgreSQL/Redis persistence, Traefik reverse proxy for TLS termination, environment-driven configuration, and a decoupled frontend/API backend structure.
|
Docker Compose-based microservices architecture with frontend/backend separation, PostgreSQL/Redis data layer, Traefik reverse proxy integration, and environment-driven configuration management following twelve-factor app principles.
|
||||||
## tags
|
## tags
|
||||||
docker, redis, git, application, postgresql, compose, traefik, project
|
docker, redis, git, application, postgresql, compose, traefik, project
|
||||||
## symbols
|
## symbols
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
dir: apps
|
dir: apps
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Contains the main executable application modules that serve as entry points for the project.
|
Contains the main deployable application modules or entry points for the project.
|
||||||
## parent
|
## parent
|
||||||
index: ./.pi-map.index.md
|
index: ./.pi-map.index.md
|
||||||
map: ./.pi-map.md
|
map: ./.pi-map.md
|
||||||
|
|||||||
+2
-2
@@ -4,10 +4,10 @@ dir: apps
|
|||||||
index: apps/.pi-map.index.md
|
index: apps/.pi-map.index.md
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Contains the main executable application modules that serve as entry points for the project.
|
Contains the main deployable application modules or entry points for the project.
|
||||||
## files
|
## files
|
||||||
## arch
|
## arch
|
||||||
Modular application structure with separate deployable units, likely following microservices or layered architecture patterns with domain-driven design boundaries.
|
Modular monolith or microservices architecture with separate application boundaries, each potentially having its own configuration, dependencies, and lifecycle.
|
||||||
## tags
|
## tags
|
||||||
-
|
-
|
||||||
## symbols
|
## symbols
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ Self-hosted FastAPI backend API that manages projects, git repositories, and dev
|
|||||||
- uv.lock | Lock file for the uv Python package manager that pins exact dependency versions and their artifact hashes for reproducible installations | dep: uv, Python 3.11+, aiosqlite, alembic, annotated-doc, annotated-types, anyio, ast-serialize, asyncpg, and many other PyPI packages
|
- uv.lock | Lock file for the uv Python package manager that pins exact dependency versions and their artifact hashes for reproducible installations | dep: uv, Python 3.11+, aiosqlite, alembic, annotated-doc, annotated-types, anyio, ast-serialize, asyncpg, and many other PyPI packages
|
||||||
- wait-for-db.sh | Wait for a PostgreSQL database to become available before executing a command, with configurable retry logic. | dep: nc (netcat), sh (POSIX shell), sleep
|
- wait-for-db.sh | Wait for a PostgreSQL database to become available before executing a command, with configurable retry logic. | dep: nc (netcat), sh (POSIX shell), sleep
|
||||||
## arch
|
## arch
|
||||||
Async Python/FastAPI backend with PostgreSQL (asyncpg), Alembic migrations, multi-stage Docker deployment with Cloudflare tunneling, uv package management, and containerized orchestration with database dependency waiting.
|
Async Python/FastAPI with PostgreSQL (Alembic migrations), multi-stage Docker deployment with Cloudflare tunneling, uv package management, and containerized service orchestration.
|
||||||
## tags
|
## tags
|
||||||
docker, alembic, python, database, fastapi, postgresql, asyncpg, uvicorn
|
docker, alembic, python, database, fastapi, postgresql, asyncpg, uvicorn
|
||||||
## symbols
|
## symbols
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
dir: apps/api/src
|
dir: apps/api/src
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Core application package for the Headquarter API, providing configuration, database connectivity, logging infrastructure, and FastAPI application initialization.
|
Core API application package that initializes and configures the Headquarter FastAPI backend with database, authentication, logging, and middleware infrastructure.
|
||||||
## parent
|
## parent
|
||||||
index: apps/api/.pi-map.index.md
|
index: apps/api/.pi-map.index.md
|
||||||
map: apps/api/.pi-map.md
|
map: apps/api/.pi-map.md
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ dir: apps/api/src
|
|||||||
index: apps/api/src/.pi-map.index.md
|
index: apps/api/src/.pi-map.index.md
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Core application package for the Headquarter API, providing configuration, database connectivity, structured logging, and FastAPI application initialization.
|
Core API application package that initializes and configures the Headquarter FastAPI backend with database, authentication, logging, and middleware infrastructure.
|
||||||
## files
|
## files
|
||||||
- __init__.py | Marks the directory as a Python package for the Headquarter API.
|
- __init__.py | Marks the directory as a Python package for the Headquarter API.
|
||||||
- config.py | Defines application configuration settings with environment-based overrides using Pydantic, including database URLs, service domains, OAuth/Authentik integration, JWT/session settings, and computed properties for environment-specific behavior. | exp: class:Settings, func:build_database_url(user: str, password: str, host: str, port: int, database: str) → str | dep: pydantic, pydantic_settings
|
- config.py | Defines application configuration settings with environment-based overrides using Pydantic, including database URLs, service domains, OAuth/Authentik integration, JWT/session settings, and computed properties for environment-specific behavior. | exp: class:Settings, func:build_database_url(user: str, password: str, host: str, port: int, database: str) → str | dep: pydantic, pydantic_settings
|
||||||
@@ -12,7 +12,7 @@ Core application package for the Headquarter API, providing configuration, datab
|
|||||||
- logging_config.py | Configures structured JSON logging with correlation ID injection, custom formatters, and HTTP request/exception middleware for a FastAPI application. | exp: class:CorrelationIdFilter, method:filter(self, record: logging.LogRecord) → bool, call:get_correlation_id, class:JSONFormatter, method:format(self, record: logging.LogRecord) → str, call:self.formatTime, call:record.getMessage, call:getattr, call:self.formatException, call:json.dumps, method:formatTime(self, record: logging.LogRecord, datefmt) → str, call:time.strftime, call:time.gmtime, class:RequestLoggingMiddleware, method:dispatch(self, request: Request, call_next: Callable) → Response, call:time.time, call:logger.info, call:call_next, call:int, call:logger.error, call:type, call:traceback.format_exc, class:ExceptionLoggingMiddleware, method:dispatch(self, request: Request, call_next: Callable) → Response, call:call_next, call:logger.critical, call:traceback.format_exc, func:configure_logging(level) → None, call:JSONFormatter, call:logging.StreamHandler, call:console_handler.setFormatter, call:console_handler.addFilter, call:CorrelationIdFilter, call:root_logger.setLevel, call:logging.getLogger("uvicorn").setLevel, call:logging.getLogger("uvicorn.access").setLevel, call:logging.getLogger("sqlalchemy.engine").setLevel, call:logger.info, call:logging.getLevelName | dep: json, logging, sys, time, traceback, collections.abc, fastapi, starlette.middleware.base, src.services.shared.correlation
|
- logging_config.py | Configures structured JSON logging with correlation ID injection, custom formatters, and HTTP request/exception middleware for a FastAPI application. | exp: class:CorrelationIdFilter, method:filter(self, record: logging.LogRecord) → bool, call:get_correlation_id, class:JSONFormatter, method:format(self, record: logging.LogRecord) → str, call:self.formatTime, call:record.getMessage, call:getattr, call:self.formatException, call:json.dumps, method:formatTime(self, record: logging.LogRecord, datefmt) → str, call:time.strftime, call:time.gmtime, class:RequestLoggingMiddleware, method:dispatch(self, request: Request, call_next: Callable) → Response, call:time.time, call:logger.info, call:call_next, call:int, call:logger.error, call:type, call:traceback.format_exc, class:ExceptionLoggingMiddleware, method:dispatch(self, request: Request, call_next: Callable) → Response, call:call_next, call:logger.critical, call:traceback.format_exc, func:configure_logging(level) → None, call:JSONFormatter, call:logging.StreamHandler, call:console_handler.setFormatter, call:console_handler.addFilter, call:CorrelationIdFilter, call:root_logger.setLevel, call:logging.getLogger("uvicorn").setLevel, call:logging.getLogger("uvicorn.access").setLevel, call:logging.getLogger("sqlalchemy.engine").setLevel, call:logger.info, call:logging.getLevelName | dep: json, logging, sys, time, traceback, collections.abc, fastapi, starlette.middleware.base, src.services.shared.correlation
|
||||||
- main.py | Initializes and configures a FastAPI application for the "Headquarter API" with database setup, middleware, routing, and background services. | exp: func:_sanitize_validation_errors(errors), call:error.get, call:str, call:ctx.items, call:isinstance, call:type, call:sanitized.append, func:validation_exception_handler(request: Request, exc: RequestValidationError), call:exc.errors, call:logger.warning, call:_sanitize_validation_errors, call:JSONResponse, func:on_startup(), call:logger.info, call:init_database, call:logger.error, call:sys.exit, call:_health_monitor.start, call:seed_builtin_tool_types, func:on_shutdown(), call:logger.info, call:_health_monitor.stop | dep: logging, os, fastapi, fastapi.exceptions, fastapi.middleware.cors, fastapi.responses, fastapi.staticfiles, src.api.config, src.api.project, src.api.system, src.api.tool, src.api.user, src.api.workspace, src.config, src.models, src.database, src.logging_config, src.seeds.builtin_tool_types, src.services.instance, src.services.shared, sys, src.api.*
|
- main.py | Initializes and configures a FastAPI application for the "Headquarter API" with database setup, middleware, routing, and background services. | exp: func:_sanitize_validation_errors(errors), call:error.get, call:str, call:ctx.items, call:isinstance, call:type, call:sanitized.append, func:validation_exception_handler(request: Request, exc: RequestValidationError), call:exc.errors, call:logger.warning, call:_sanitize_validation_errors, call:JSONResponse, func:on_startup(), call:logger.info, call:init_database, call:logger.error, call:sys.exit, call:_health_monitor.start, call:seed_builtin_tool_types, func:on_shutdown(), call:logger.info, call:_health_monitor.stop | dep: logging, os, fastapi, fastapi.exceptions, fastapi.middleware.cors, fastapi.responses, fastapi.staticfiles, src.api.config, src.api.project, src.api.system, src.api.tool, src.api.user, src.api.workspace, src.config, src.models, src.database, src.logging_config, src.seeds.builtin_tool_types, src.services.instance, src.services.shared, sys, src.api.*
|
||||||
## arch
|
## arch
|
||||||
Layered architecture with environment-based Pydantic config, async SQLAlchemy with retry patterns, structured JSON logging with correlation ID tracking, and modular FastAPI setup with middleware pipeline.
|
Layered architecture using Pydantic for environment-based configuration, async SQLAlchemy with Alembic migrations, structured JSON logging with correlation IDs, and FastAPI middleware/routing pattern for a service-oriented backend.
|
||||||
## tags
|
## tags
|
||||||
src, database, logging, call:logger.info, api, middleware, fastapi, filter
|
src, database, logging, call:logger.info, api, middleware, fastapi, filter
|
||||||
## symbols
|
## symbols
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
dir: apps/api/src/api
|
dir: apps/api/src/api
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Defines shared API infrastructure and reusable validation utilities for the API layer.
|
Defines shared API infrastructure including reusable Pydantic validators for consistent input validation across API endpoints.
|
||||||
## parent
|
## parent
|
||||||
index: apps/api/src/.pi-map.index.md
|
index: apps/api/src/.pi-map.index.md
|
||||||
map: apps/api/src/.pi-map.md
|
map: apps/api/src/.pi-map.md
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ dir: apps/api/src/api
|
|||||||
index: apps/api/src/api/.pi-map.index.md
|
index: apps/api/src/api/.pi-map.index.md
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Defines shared API infrastructure and reusable validation utilities for the API layer.
|
Defines shared API infrastructure including reusable Pydantic validators for consistent input validation across API endpoints.
|
||||||
## files
|
## files
|
||||||
- __init__.py | Marks the directory as a Python package for API routers.
|
- __init__.py | Marks the directory as a Python package for API routers.
|
||||||
- shared_validators.py | Provides reusable Pydantic validator functions for API schema validation including mount paths, files, environment variables, and volume mounts. | exp: func:validate_mount_path(v: str | None) → str | None, call:v.startswith, raise:ValueError, func:validate_files(v: dict | None, max_size_bytes) → dict | None, call:v.items, call:path.startswith, call:len, call:content.encode, raise:ValueError, func:validate_env_vars(v: dict | None) → dict | None, call:isinstance, raise:ValueError, func:validate_volumes(v: list | None) → list | None, call:isinstance, call:enumerate, raise:ValueError
|
- shared_validators.py | Provides reusable Pydantic validator functions for API schema validation including mount paths, files, environment variables, and volume mounts. | exp: func:validate_mount_path(v: str | None) → str | None, call:v.startswith, raise:ValueError, func:validate_files(v: dict | None, max_size_bytes) → dict | None, call:v.items, call:path.startswith, call:len, call:content.encode, raise:ValueError, func:validate_env_vars(v: dict | None) → dict | None, call:isinstance, raise:ValueError, func:validate_volumes(v: list | None) → list | None, call:isinstance, call:enumerate, raise:ValueError
|
||||||
## arch
|
## arch
|
||||||
Modular package structure with shared Pydantic validators for cross-cutting schema validation concerns.
|
Modular utility package with functional validation helpers using Pydantic for declarative schema enforcement.
|
||||||
## tags
|
## tags
|
||||||
validate, raise:value, error, call:isinstance, mount, api, init, path
|
validate, raise:value, error, call:isinstance, mount, api, init, path
|
||||||
## symbols
|
## symbols
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
dir: apps/api/src/api/workspace
|
dir: apps/api/src/api/workspace
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Provides FastAPI REST API endpoints for workspace management, including CRUD operations, file access, git version control, and tool instance management within user-scoped workspaces.
|
Provides FastAPI REST endpoints for workspace management, file operations, git integration, and tool instance management within user workspaces.
|
||||||
## parent
|
## parent
|
||||||
index: apps/api/src/api/.pi-map.index.md
|
index: apps/api/src/api/.pi-map.index.md
|
||||||
map: apps/api/src/api/.pi-map.md
|
map: apps/api/src/api/.pi-map.md
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ dir: apps/api/src/api/workspace
|
|||||||
index: apps/api/src/api/workspace/.pi-map.index.md
|
index: apps/api/src/api/workspace/.pi-map.index.md
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Provides FastAPI REST API endpoints for workspace management, including CRUD operations, file access, git version control, and tool instance management within user-scoped workspaces.
|
Provides FastAPI REST endpoints for workspace management, file operations, git integration, and tool instance management within user workspaces.
|
||||||
## files
|
## files
|
||||||
- __init__.py | Aggregates and re-exports workspace API router modules for centralized access | dep: src.api.workspace.workspace_files, src.api.workspace.workspace_git, src.api.workspace.workspace_instances, src.api.workspace.workspaces
|
- __init__.py | Aggregates and re-exports workspace API router modules for centralized access | dep: src.api.workspace.workspace_files, src.api.workspace.workspace_git, src.api.workspace.workspace_instances, src.api.workspace.workspaces
|
||||||
- workspace_files.py | Provides FastAPI endpoints for listing, reading, and writing files within user workspaces with optional git commit integration. | exp: func:_get_workspace(session: AsyncSession, workspace_id: uuid.UUID, user_id: uuid.UUID) → Workspace, call:session.execute, call:select(Workspace).where, call:result.scalar_one_or_none, raise:HTTPException, func:list_files(workspace_id: uuid.UUID, path, user_id, session) → dict, call:_get_workspace, call:FileService, call:service.list_directory, raise:HTTPException, func:get_file_content(workspace_id: uuid.UUID, path: str, user_id, session) → dict, call:_get_workspace, call:FileService, call:service.read_file, raise:HTTPException, func:write_file(workspace_id: uuid.UUID, data: dict, user_id, session) → dict, call:_get_workspace, call:FileService, call:data.get("path", "").strip, call:data.get("message", "").strip, call:service.write_file, call:GitOperations, call:git.commit, raise:HTTPException | dep: uuid, fastapi, sqlalchemy.ext.asyncio, src.auth.dependencies, src.models, src.services.shared.file_service, sqlalchemy, src.services.git.git_operations
|
- workspace_files.py | Provides FastAPI endpoints for listing, reading, and writing files within user workspaces with optional git commit integration. | exp: func:_get_workspace(session: AsyncSession, workspace_id: uuid.UUID, user_id: uuid.UUID) → Workspace, call:session.execute, call:select(Workspace).where, call:result.scalar_one_or_none, raise:HTTPException, func:list_files(workspace_id: uuid.UUID, path, user_id, session) → dict, call:_get_workspace, call:FileService, call:service.list_directory, raise:HTTPException, func:get_file_content(workspace_id: uuid.UUID, path: str, user_id, session) → dict, call:_get_workspace, call:FileService, call:service.read_file, raise:HTTPException, func:write_file(workspace_id: uuid.UUID, data: dict, user_id, session) → dict, call:_get_workspace, call:FileService, call:data.get("path", "").strip, call:data.get("message", "").strip, call:service.write_file, call:GitOperations, call:git.commit, raise:HTTPException | dep: uuid, fastapi, sqlalchemy.ext.asyncio, src.auth.dependencies, src.models, src.services.shared.file_service, sqlalchemy, src.services.git.git_operations
|
||||||
- workspace_git.py | Provides FastAPI REST endpoints for git operations (status, branches, commit, push, pull, fetch, checkout, history) scoped to user workspaces. | exp: func:_get_workspace(session: AsyncSession, workspace_id: uuid.UUID, user_id: uuid.UUID) → Workspace, call:session.execute, call:select(Workspace).where, call:result.scalar_one_or_none, raise:HTTPException, func:git_status(workspace_id: uuid.UUID, user_id, session) → dict, call:_get_workspace, call:GitOperations, call:git.status, raise:HTTPException, func:git_branches(workspace_id: uuid.UUID, user_id, session) → dict, call:_get_workspace, call:GitOperations, call:git.branches, raise:HTTPException, func:git_commit(workspace_id: uuid.UUID, data: dict, user_id, session) → dict, call:_get_workspace, call:data.get("message", "").strip, call:GitOperations, call:git.commit, raise:HTTPException, func:git_push(workspace_id: uuid.UUID, user_id, session) → dict, call:_get_workspace, call:GitOperations, call:git.push, raise:HTTPException, func:git_pull(workspace_id: uuid.UUID, user_id, session) → dict, call:_get_workspace, call:GitOperations, call:git.pull, raise:HTTPException, func:git_fetch(workspace_id: uuid.UUID, user_id, session) → dict, call:_get_workspace, call:GitOperations, call:git.fetch, raise:HTTPException, func:git_checkout(workspace_id: uuid.UUID, data: dict, user_id, session) → dict, call:_get_workspace, call:data.get("branch", "").strip, call:GitOperations, call:git.checkout, call:session.commit, raise:HTTPException, func:git_history(workspace_id: uuid.UUID, path, limit, user_id, session) → dict, call:_get_workspace, call:GitOperations, call:git.history, raise:HTTPException | dep: uuid, fastapi, sqlalchemy.ext.asyncio, src.auth.dependencies, src.models, src.services.git.git_operations, sqlalchemy
|
- workspace_git.py | Provides FastAPI REST endpoints for git operations (status, branches, commit, push, pull, fetch, checkout, history) scoped to user workspaces. | exp: func:_get_workspace(session: AsyncSession, workspace_id: uuid.UUID, user_id: uuid.UUID) → Workspace, call:session.execute, call:select(Workspace).where, call:result.scalar_one_or_none, raise:HTTPException, func:git_status(workspace_id: uuid.UUID, user_id, session) → dict, call:_get_workspace, call:GitOperations, call:git.status, raise:HTTPException, func:git_branches(workspace_id: uuid.UUID, user_id, session) → dict, call:_get_workspace, call:GitOperations, call:git.branches, raise:HTTPException, func:git_commit(workspace_id: uuid.UUID, data: dict, user_id, session) → dict, call:_get_workspace, call:data.get("message", "").strip, call:GitOperations, call:git.commit, raise:HTTPException, func:git_push(workspace_id: uuid.UUID, user_id, session) → dict, call:_get_workspace, call:GitOperations, call:git.push, raise:HTTPException, func:git_pull(workspace_id: uuid.UUID, user_id, session) → dict, call:_get_workspace, call:GitOperations, call:git.pull, raise:HTTPException, func:git_fetch(workspace_id: uuid.UUID, user_id, session) → dict, call:_get_workspace, call:GitOperations, call:git.fetch, raise:HTTPException, func:git_checkout(workspace_id: uuid.UUID, data: dict, user_id, session) → dict, call:_get_workspace, call:data.get("branch", "").strip, call:GitOperations, call:git.checkout, call:session.commit, raise:HTTPException, func:git_history(workspace_id: uuid.UUID, path, limit, user_id, session) → dict, call:_get_workspace, call:GitOperations, call:git.history, raise:HTTPException | dep: uuid, fastapi, sqlalchemy.ext.asyncio, src.auth.dependencies, src.models, src.services.git.git_operations, sqlalchemy
|
||||||
- workspace_instances.py | FastAPI router providing endpoints to create and list tool instances associated with a specific workspace. | exp: func:_get_workspace(session: AsyncSession, workspace_id: uuid.UUID, user_id: uuid.UUID) → Workspace, call:session.execute, call:select(Workspace).where, call:result.scalar_one_or_none, raise:HTTPException, func:create_workspace_instance(workspace_id: uuid.UUID, data: CreateWorkspaceInstanceRequest, user_id, session) → dict, call:_get_workspace, call:session.get, call:CreateInstanceRequest, call:str, call:create_tool_instance, call:instance.created_at.isoformat, raise:HTTPException, func:list_workspace_instances(workspace_id: uuid.UUID, user_id, session) → list[dict], call:_get_workspace, call:session.execute, call:select(ToolInstance) .where(ToolInstance.workspace_id == workspace_id) .order_by, call:ToolInstance.created_at.desc, call:result.scalars().all, call:str, call:i.created_at.isoformat | dep: uuid, fastapi, sqlalchemy, sqlalchemy.ext.asyncio, src.auth.dependencies, src.models, src.schemas.tool, src.services.tool.instance_service
|
- workspace_instances.py | FastAPI router providing endpoints to create and list tool instances associated with a specific workspace. | exp: func:_get_workspace(session: AsyncSession, workspace_id: uuid.UUID, user_id: uuid.UUID) → Workspace, call:session.execute, call:select(Workspace).where, call:result.scalar_one_or_none, raise:HTTPException, func:create_workspace_instance(workspace_id: uuid.UUID, data: CreateWorkspaceInstanceRequest, user_id, session) → dict, call:_get_workspace, call:session.get, call:CreateInstanceRequest, call:str, call:create_tool_instance, call:instance.created_at.isoformat, raise:HTTPException, func:list_workspace_instances(workspace_id: uuid.UUID, user_id, session) → list[dict], call:_get_workspace, call:session.execute, call:select(ToolInstance) .where(ToolInstance.workspace_id == workspace_id) .order_by, call:ToolInstance.created_at.desc, call:result.scalars().all, call:str, call:i.created_at.isoformat | dep: uuid, fastapi, sqlalchemy, sqlalchemy.ext.asyncio, src.auth.dependencies, src.models, src.schemas.tool, src.services.tool.instance_service
|
||||||
- workspaces.py | Provides FastAPI CRUD endpoints for managing Git repository workspaces with nested and top-level URL structures, including listing, creating, updating, deleting, and syncing workspaces with instance count tracking. | exp: func:list_all_workspaces(user_id, session) → list[dict], call:select(func.count(ToolInstance.id)) .where(ToolInstance.workspace_id == Workspace.id) .correlate(Workspace) .scalar_subquery, call:func.count, call:session.execute, call:select( Workspace, GitRepository.name.label("repo_name"), GitRepository.project_id, GitRepository.ssh_key_id.label("repo_ssh_key_id"), instance_count.label("instance_count"), ) .join(GitRepository, Workspace.repo_id == GitRepository.id) .where(Workspace.user_id == user_id) .order_by, call:GitRepository.name.label, call:GitRepository.ssh_key_id.label, call:instance_count.label, call:Workspace.created_at.desc, call:result.all, call:str, call:ws.last_sync_at.isoformat, call:ws.created_at.isoformat, call:ws.updated_at.isoformat, func:delete_workspace_top_level(workspace_id: uuid.UUID, force, user_id, session) → dict, call:session.get, call:WorkspaceManager, call:manager.delete, call:session.commit, call:session.rollback, call:logger.error, raise:HTTPException, func:create_workspace_top_level(data: dict, user_id, session) → dict, call:data.get("repo_id", "").strip, call:uuid.UUID, call:session.get, call:data.get("name", "").strip, call:data.get("branch", "main").strip, call:WorkspaceManager, call:manager.create, call:session.add, call:session.commit, call:session.rollback, call:logger.error, call:session.refresh, call:str, call:workspace.created_at.isoformat, raise:HTTPException, func:list_workspaces(project_id: uuid.UUID, repo_id: uuid.UUID, user_id, session) → list[dict], call:_get_repo, call:select(func.count(ToolInstance.id)) .where(ToolInstance.workspace_id == Workspace.id) .correlate(Workspace) .scalar_subquery, call:func.count, call:session.execute, call:select( Workspace, instance_count.label("instance_count"), ) .where(Workspace.repo_id == repo_id) .order_by, call:instance_count.label, call:Workspace.created_at.desc, call:result.all, call:str, call:ws.last_sync_at.isoformat, call:ws.created_at.isoformat, call:ws.updated_at.isoformat, func:create_workspace(project_id: uuid.UUID, repo_id: uuid.UUID, data: dict, user_id, session) → dict, call:_get_repo, call:data.get("name", "").strip, call:data.get("branch", "main").strip, call:WorkspaceManager, call:manager.create, call:session.add, call:session.commit, call:session.rollback, call:logger.error, call:session.refresh, call:str, call:workspace.created_at.isoformat, raise:HTTPException, func:get_workspace_detail(project_id: uuid.UUID, repo_id: uuid.UUID, workspace_id: uuid.UUID, user_id, session) → dict, call:_get_repo, call:_get_workspace, call:session.execute, call:select(func.count(ToolInstance.id)).where, call:func.count, call:result.scalar, call:str, call:workspace.last_sync_at.isoformat, call:workspace.created_at.isoformat, call:workspace.updated_at.isoformat, func:update_workspace(project_id: uuid.UUID, repo_id: uuid.UUID, workspace_id: uuid.UUID, data: dict, user_id, session) → dict, call:_get_repo, call:_get_workspace, call:data.get("name", "").strip, call:data.get("branch", "").strip, call:session.commit, call:session.rollback, call:logger.error, call:str, raise:HTTPException, func:delete_workspace(project_id: uuid.UUID, repo_id: uuid.UUID, workspace_id: uuid.UUID, force, user_id, session) → dict, call:_get_repo, call:_get_workspace, call:WorkspaceManager, call:manager.delete, call:session.commit, call:session.rollback, call:logger.error, raise:HTTPException, func:sync_workspace(project_id: uuid.UUID, repo_id: uuid.UUID, workspace_id: uuid.UUID, user_id, session) → dict, call:_get_repo, call:_get_workspace, call:WorkspaceManager, call:manager.sync, call:session.commit, call:workspace.last_sync_at.isoformat, raise:HTTPException, func:_get_repo(session: AsyncSession, repo_id: uuid.UUID, project_id: uuid.UUID, user_id: uuid.UUID) → GitRepository, call:session.execute, call:select(GitRepository) .where( GitRepository.id == repo_id, GitRepository.project_id == project_id, ) .options, call:selectinload, call:result.scalar_one_or_none, raise:HTTPException, func:_get_workspace(session: AsyncSession, workspace_id: uuid.UUID, repo_id: uuid.UUID) → Workspace, call:session.execute, call:select(Workspace).where, call:result.scalar_one_or_none, raise:HTTPException | dep: logging, uuid, fastapi, sqlalchemy, sqlalchemy.ext.asyncio, sqlalchemy.orm, src.auth.dependencies, src.models, src.services.shared.workspace_manager
|
- workspaces.py | FastAPI router providing CRUD endpoints for workspace management with nested and top-level URL structures, including listing, creating, updating, deleting, and syncing workspaces tied to Git repositories. | exp: func:list_all_workspaces(user_id, session) → list[dict], call:select(func.count(ToolInstance.id)) .where(ToolInstance.workspace_id == Workspace.id) .correlate(Workspace) .scalar_subquery, call:func.count, call:session.execute, call:select( Workspace, GitRepository, instance_count.label("instance_count"), ) .join(GitRepository, Workspace.repo_id == GitRepository.id) .options(selectinload(GitRepository.project)) .where(Workspace.user_id == user_id) .order_by, call:instance_count.label, call:selectinload, call:Workspace.created_at.desc, call:result.all, call:str, call:ws.last_sync_at.isoformat, call:ws.created_at.isoformat, call:ws.updated_at.isoformat, func:delete_workspace_top_level(workspace_id: uuid.UUID, force, user_id, session) → dict, call:session.get, call:WorkspaceManager, call:manager.delete, call:session.commit, call:session.rollback, call:logger.error, raise:HTTPException, func:create_workspace_top_level(data: dict, user_id, session) → dict, call:data.get("repo_id", "").strip, call:uuid.UUID, call:session.get, call:data.get("name", "").strip, call:data.get("branch", "main").strip, call:WorkspaceManager, call:manager.create, call:session.add, call:session.commit, call:session.rollback, call:logger.error, call:session.refresh, call:str, call:workspace.created_at.isoformat, raise:HTTPException, func:list_workspaces(project_id: uuid.UUID, repo_id: uuid.UUID, user_id, session) → list[dict], call:_get_repo, call:select(func.count(ToolInstance.id)) .where(ToolInstance.workspace_id == Workspace.id) .correlate(Workspace) .scalar_subquery, call:func.count, call:session.execute, call:select( Workspace, instance_count.label("instance_count"), ) .where(Workspace.repo_id == repo_id) .order_by, call:instance_count.label, call:Workspace.created_at.desc, call:result.all, call:str, call:ws.last_sync_at.isoformat, call:ws.created_at.isoformat, call:ws.updated_at.isoformat, func:create_workspace(project_id: uuid.UUID, repo_id: uuid.UUID, data: dict, user_id, session) → dict, call:_get_repo, call:data.get("name", "").strip, call:data.get("branch", "main").strip, call:WorkspaceManager, call:manager.create, call:session.add, call:session.commit, call:session.rollback, call:logger.error, call:session.refresh, call:str, call:workspace.created_at.isoformat, raise:HTTPException, func:get_workspace_detail(project_id: uuid.UUID, repo_id: uuid.UUID, workspace_id: uuid.UUID, user_id, session) → dict, call:_get_repo, call:_get_workspace, call:session.execute, call:select(func.count(ToolInstance.id)).where, call:func.count, call:result.scalar, call:str, call:workspace.last_sync_at.isoformat, call:workspace.created_at.isoformat, call:workspace.updated_at.isoformat, func:update_workspace(project_id: uuid.UUID, repo_id: uuid.UUID, workspace_id: uuid.UUID, data: dict, user_id, session) → dict, call:_get_repo, call:_get_workspace, call:data.get("name", "").strip, call:data.get("branch", "").strip, call:session.commit, call:session.rollback, call:logger.error, call:str, raise:HTTPException, func:delete_workspace(project_id: uuid.UUID, repo_id: uuid.UUID, workspace_id: uuid.UUID, force, user_id, session) → dict, call:_get_repo, call:_get_workspace, call:WorkspaceManager, call:manager.delete, call:session.commit, call:session.rollback, call:logger.error, raise:HTTPException, func:sync_workspace(project_id: uuid.UUID, repo_id: uuid.UUID, workspace_id: uuid.UUID, user_id, session) → dict, call:_get_repo, call:_get_workspace, call:WorkspaceManager, call:manager.sync, call:session.commit, call:workspace.last_sync_at.isoformat, raise:HTTPException, func:_get_repo(session: AsyncSession, repo_id: uuid.UUID, project_id: uuid.UUID, user_id: uuid.UUID) → GitRepository, call:session.execute, call:select(GitRepository) .where( GitRepository.id == repo_id, GitRepository.project_id == project_id, ) .options, call:selectinload, call:result.scalar_one_or_none, raise:HTTPException, func:_get_workspace(session: AsyncSession, workspace_id: uuid.UUID, repo_id: uuid.UUID) → Workspace, call:session.execute, call:select(Workspace).where, call:result.scalar_one_or_none, raise:HTTPException | dep: logging, uuid, fastapi, sqlalchemy, sqlalchemy.ext.asyncio, sqlalchemy.orm, src.auth.dependencies, src.models, src.services.shared.workspace_manager
|
||||||
## arch
|
## arch
|
||||||
Modular router-based architecture using FastAPI with domain-driven decomposition into separate modules (files, git, instances, workspaces), nested URL routing for hierarchical resources, and optional git integration for file operations.
|
Modular FastAPI router pattern with domain-driven separation (files, git, instances, workspaces) using nested URL structures and git-backed workspace synchronization.
|
||||||
## tags
|
## tags
|
||||||
workspace, get, raise:httpexception, call:, at.isoformat, git, call:select, call:data.get
|
workspace, get, raise:httpexception, call:, at.isoformat, git, call:select, call:data.get
|
||||||
## symbols
|
## symbols
|
||||||
|
|||||||
@@ -36,12 +36,11 @@ async def list_all_workspaces(
|
|||||||
result = await session.execute(
|
result = await session.execute(
|
||||||
select(
|
select(
|
||||||
Workspace,
|
Workspace,
|
||||||
GitRepository.name.label("repo_name"),
|
GitRepository,
|
||||||
GitRepository.project_id,
|
|
||||||
GitRepository.ssh_key_id.label("repo_ssh_key_id"),
|
|
||||||
instance_count.label("instance_count"),
|
instance_count.label("instance_count"),
|
||||||
)
|
)
|
||||||
.join(GitRepository, Workspace.repo_id == GitRepository.id)
|
.join(GitRepository, Workspace.repo_id == GitRepository.id)
|
||||||
|
.options(selectinload(GitRepository.project))
|
||||||
.where(Workspace.user_id == user_id)
|
.where(Workspace.user_id == user_id)
|
||||||
.order_by(Workspace.created_at.desc())
|
.order_by(Workspace.created_at.desc())
|
||||||
)
|
)
|
||||||
@@ -51,11 +50,11 @@ async def list_all_workspaces(
|
|||||||
{
|
{
|
||||||
"id": str(ws.id),
|
"id": str(ws.id),
|
||||||
"name": ws.name,
|
"name": ws.name,
|
||||||
"repo_id": str(ws.repo_id),
|
"repo_id": str(repo.id),
|
||||||
"repo_name": repo_name or "",
|
"repo_name": repo.name or "",
|
||||||
"repo_ssh_key_id": str(ssh_key_id) if ssh_key_id else None,
|
"repo_ssh_key_id": str(repo.ssh_key_id) if repo.ssh_key_id else None,
|
||||||
"project_id": str(project_id) if project_id else "",
|
"project_id": str(repo.project_id) if repo.project_id else "",
|
||||||
"project_name": "",
|
"project_name": repo.project.name if repo.project else "",
|
||||||
"user_id": str(ws.user_id),
|
"user_id": str(ws.user_id),
|
||||||
"branch": ws.branch,
|
"branch": ws.branch,
|
||||||
"path": ws.path,
|
"path": ws.path,
|
||||||
@@ -65,7 +64,7 @@ async def list_all_workspaces(
|
|||||||
"updated_at": ws.updated_at.isoformat() if ws.updated_at else None,
|
"updated_at": ws.updated_at.isoformat() if ws.updated_at else None,
|
||||||
"instance_count": count or 0,
|
"instance_count": count or 0,
|
||||||
}
|
}
|
||||||
for ws, repo_name, project_id, ssh_key_id, count in rows
|
for ws, repo, count in rows
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
dir: apps/web
|
dir: apps/web
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Frontend web application for the headquarters system, providing a browser-based UI with code editing, terminal, and routing capabilities.
|
Frontend web application providing a React-based UI with code editing, terminal, and routing capabilities for the "headquarter" project.
|
||||||
## parent
|
## parent
|
||||||
index: apps/.pi-map.index.md
|
index: apps/.pi-map.index.md
|
||||||
map: apps/.pi-map.md
|
map: apps/.pi-map.md
|
||||||
|
|||||||
+2
-2
@@ -4,7 +4,7 @@ dir: apps/web
|
|||||||
index: apps/web/.pi-map.index.md
|
index: apps/web/.pi-map.index.md
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Frontend web application for the headquarters system, providing a browser-based UI with code editing, terminal, and routing capabilities.
|
Frontend web application providing a React-based UI with code editing, terminal, and routing capabilities for the "headquarter" project.
|
||||||
## files
|
## files
|
||||||
- .env.example | Template file defining example environment variables for frontend API and application URL configuration
|
- .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
|
- .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 @@ Frontend web application for the headquarters system, providing a browser-based
|
|||||||
- tsconfig.json | TypeScript configuration file for a React project using Vite with modern ES2020 target and bundler module resolution | dep: typescript, react, vite
|
- 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
|
- 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
|
## arch
|
||||||
Modern React SPA built with Vite and TypeScript, containerized with multi-stage Docker/nginx deployment, using ES modules with Vitest for testing.
|
Modern React SPA built with Vite and TypeScript, using nginx for production serving with client-side routing, multi-stage Docker deployment, and Vitest for testing.
|
||||||
## tags
|
## tags
|
||||||
react, eslint, vite, typescript, dom, application, nginx, web
|
react, eslint, vite, typescript, dom, application, nginx, web
|
||||||
## symbols
|
## symbols
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Frontend web application entry point and core infrastructure for a React-based c
|
|||||||
- 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
|
- 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
|
- types.ts | Defines TypeScript type definitions for user sessions, projects, repositories, and workspaces in an application. | exp: SessionUser, SessionPayload, Project, WorkspaceSummary, RepositorySummary, ProjectWithRepos
|
||||||
## arch
|
## arch
|
||||||
Provider-composition pattern with React Router v6 nested route declarations, centralized type definitions, and layered authentication/session management wrapping a protected route hierarchy.
|
Modular React SPA using React Router v6 with nested route layouts, protected route guards via authentication context, and centralized TypeScript domain models for session/workspace/project entities.
|
||||||
## tags
|
## tags
|
||||||
pages, styles, css, router, react, session, dom, project
|
pages, styles, css, router, react, session, dom, project
|
||||||
## symbols
|
## symbols
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
dir: apps/web/src/components
|
dir: apps/web/src/components
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Provides foundational, reusable React UI components and utilities for rendering layouts, interactive elements, data states, icons, code editing, routing guards, and toast notifications across the web application.
|
Provides reusable, accessible UI components and utilities for rendering the application shell, data states, icons, code display, notifications, and route protection in a React web application.
|
||||||
## parent
|
## parent
|
||||||
index: apps/web/src/.pi-map.index.md
|
index: apps/web/src/.pi-map.index.md
|
||||||
map: apps/web/src/.pi-map.md
|
map: apps/web/src/.pi-map.md
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ dir: apps/web/src/components
|
|||||||
index: apps/web/src/components/.pi-map.index.md
|
index: apps/web/src/components/.pi-map.index.md
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Provides foundational, reusable React UI components and utilities for rendering layouts, interactive elements, data states, icons, code editing, routing guards, and toast notifications across the web application.
|
Provides reusable, accessible UI components and utilities for rendering the application shell, data states, icons, code display, notifications, and route protection in a React web application.
|
||||||
## files
|
## 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, ./features/notification/event-toast-bridge, ./features/notification/notification-center, ./icon, ./features/mobile/mobile-nav, ./features/tool/start-tool-fab, ../utils/icons
|
- app-shell.tsx | Renders the main application shell layout with navigation, header, session management, and mobile-responsive behavior for a React Router-based SPA. | 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, ./features/notification/event-toast-bridge, ./features/notification/notification-center, ./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
|
- 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
|
||||||
- data-states.tsx | Provides reusable React components for displaying loading, error, and empty data states in a UI. | exp: LoadingState, ErrorState, EmptyState | dep: ./icon, icon
|
- data-states.tsx | Provides reusable React components for displaying loading, error, and empty data states in a UI. | exp: LoadingState, ErrorState, EmptyState | dep: ./icon, icon
|
||||||
- icon.tsx | Provides a centralized, type-safe React icon component that maps semantic names to Phosphor icons with configurable size, weight, color, and accessibility attributes. | exp: IconName, IconProps, Icon | dep: react, @phosphor-icons/react
|
- icon.tsx | Provides a centralized, type-safe React icon component that maps semantic names to Phosphor icons with configurable size, weight, color, and accessibility attributes. | exp: IconName, IconProps, Icon | dep: react, @phosphor-icons/react
|
||||||
@@ -17,7 +17,7 @@ Provides foundational, reusable React UI components and utilities for rendering
|
|||||||
- toast-rules.test.ts | Unit tests for mapping instance events to toast notification categories and severities | dep: vitest, ./toast-rules, ../types/events
|
- 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
|
- 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
|
## arch
|
||||||
Component-based architecture with functional React patterns, custom hooks for state management, centralized icon mapping with type safety, HOC-like route guards, and utility modules for cross-cutting concerns (toast rules, data states) with co-located test files.
|
Component-based React architecture with functional components, composition patterns, separation of concerns (presentation vs logic), and test coverage for critical utilities; integrates third-party libraries (Phosphor icons, react-simple-code-editor) and React Router for SPA navigation.
|
||||||
## tags
|
## tags
|
||||||
toast, icon, react, state, code, loading, event, editor
|
toast, icon, react, state, code, loading, event, editor
|
||||||
## symbols
|
## symbols
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ const NAV_ITEMS: {
|
|||||||
badge?: "sessions";
|
badge?: "sessions";
|
||||||
}[] = [
|
}[] = [
|
||||||
{ to: "/", label: "Home", icon: "dashboard" },
|
{ to: "/", label: "Home", icon: "dashboard" },
|
||||||
{ to: "/sessions", label: "Sessions", icon: "terminal", badge: "sessions" },
|
|
||||||
{ to: "/workspaces", label: "Workspaces", icon: "folder" },
|
|
||||||
{ to: "/projects", label: "Projects", icon: "projects" },
|
{ to: "/projects", label: "Projects", icon: "projects" },
|
||||||
|
{ to: "/workspaces", label: "Workspaces", icon: "folder" },
|
||||||
|
{ to: "/sessions", label: "Sessions", icon: "terminal", badge: "sessions" },
|
||||||
{ to: "/tool-workshop", label: "Tool Workshop", icon: "settings" },
|
{ to: "/tool-workshop", label: "Tool Workshop", icon: "settings" },
|
||||||
{ to: "/config-profiles", label: "Config Profiles", icon: "folder" },
|
{ to: "/config-profiles", label: "Config Profiles", icon: "folder" },
|
||||||
{ to: "/settings", label: "Settings", icon: "settings" },
|
{ to: "/settings", label: "Settings", icon: "settings" },
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
dir: apps/web/src/components/features
|
dir: apps/web/src/components/features
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Contains reusable UI components organized by feature domain for the web application.
|
Contains reusable React components that implement specific user-facing features and functionality across the web application.
|
||||||
## parent
|
## parent
|
||||||
index: apps/web/src/components/.pi-map.index.md
|
index: apps/web/src/components/.pi-map.index.md
|
||||||
map: apps/web/src/components/.pi-map.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
|
index: apps/web/src/components/features/.pi-map.index.md
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Contains reusable UI components organized by feature domain for the web application.
|
Contains reusable React components that implement specific user-facing features and functionality across the web application.
|
||||||
## files
|
## files
|
||||||
## arch
|
## arch
|
||||||
Feature-based colocation pattern with domain-specific subdirectories grouping related components, likely using composition patterns with shared UI primitives.
|
Feature-based component organization with domain-specific UI building blocks following React composition patterns, likely co-located with related hooks, utilities, or sub-components for each feature area.
|
||||||
## tags
|
## tags
|
||||||
-
|
-
|
||||||
## symbols
|
## symbols
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
dir: apps/web/src/components/features/mobile
|
dir: apps/web/src/components/features/mobile
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Provides a complete set of mobile-optimized UI components for core application patterns including navigation, lists, detail views, editing, modals, and specialized terminal interfaces.
|
Provides mobile-optimized UI components for core application features including navigation, data views, forms, modals, and specialized terminal interfaces.
|
||||||
## parent
|
## parent
|
||||||
index: apps/web/src/components/features/.pi-map.index.md
|
index: apps/web/src/components/features/.pi-map.index.md
|
||||||
map: apps/web/src/components/features/.pi-map.md
|
map: apps/web/src/components/features/.pi-map.md
|
||||||
|
|||||||
@@ -4,22 +4,22 @@ dir: apps/web/src/components/features/mobile
|
|||||||
index: apps/web/src/components/features/mobile/.pi-map.index.md
|
index: apps/web/src/components/features/mobile/.pi-map.index.md
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Provides a complete set of mobile-optimized UI components for core application patterns including navigation, lists, detail views, editing, modals, and specialized terminal interfaces.
|
Provides mobile-optimized UI components for core application features including navigation, data views, forms, modals, and specialized terminal interfaces.
|
||||||
## files
|
## files
|
||||||
- mobile-action-sheet.tsx | Renders a mobile-optimized action sheet modal with title, configurable action buttons, and cancel option. | exp: MobileActionSheetItem, func:MobileActionSheet({ isOpen, onClose, title, actions, }: MobileActionSheetProps), call:useRef, call:useEffect, call:onClose, call:document.addEventListener, call:document.removeEventListener, call:e.stopPropagation, call:actions.map, call:action.onClick | dep: react, ../../icon, icon
|
- mobile-action-sheet.tsx | Renders a mobile-optimized action sheet modal with title, configurable action buttons, and cancel option. | exp: MobileActionSheetItem, func:MobileActionSheet({ isOpen, onClose, title, actions, }: MobileActionSheetProps), call:useRef, call:useEffect, call:onClose, call:document.addEventListener, call:document.removeEventListener, call:e.stopPropagation, call:actions.map, call:action.onClick | dep: react, ../../icon, icon
|
||||||
- mobile-detail-view.tsx | A React component that renders a mobile-optimized detail view with a header (back button, title, edit/delete actions) and a field list supporting multiple value types (text, code, JSON, boolean). | exp: MobileDetailView | dep: ../../icon, react
|
- mobile-detail-view.tsx | A React component that renders a mobile-optimized detail view with a header (back button, title, edit/delete actions) and a field list supporting multiple value types (text, code, JSON, boolean). | exp: MobileDetailView | dep: ../../icon, react
|
||||||
- mobile-edit-view.tsx | A React component that renders a mobile-optimized form for editing data with configurable field types and save/cancel actions. | exp: MobileEditView | dep: react
|
- mobile-edit-view.tsx | A React component that renders a mobile-optimized form for editing data with configurable field types and save/cancel actions. | exp: MobileEditView | dep: react
|
||||||
- mobile-fab.tsx | Renders a floating action button component for mobile with an add icon and configurable click handler and label. | exp: MobileFAB | dep: ../../icon, react, icon
|
- mobile-fab.tsx | Renders a floating action button component for mobile with an add icon and configurable click handler and label. | exp: MobileFAB | dep: ../../icon, react, icon
|
||||||
- mobile-list-view.tsx | Renders a mobile-optimized list view with optional search, custom item rendering, and empty state handling | exp: MobileListView | dep: react, ../../icon, ../../../utils/icons, icon
|
- mobile-list-view.tsx | Renders a mobile-optimized list view with optional search, empty state, and customizable item rendering | exp: MobileListView | dep: react, ../../icon, ../../../utils/icons, icon
|
||||||
- mobile-nav.tsx | Renders a mobile navigation bar with route links and expandable bottom sheets for grouped navigation items. | exp: MobileNav | dep: react, react-router-dom, ../../icon, ../tool/tools-bottom-sheet, ./spaces-bottom-sheet, ../../../utils/icons
|
- mobile-nav.tsx | Renders a mobile navigation bar with grouped items that open bottom sheets and standard items that use React Router links, including active state indicators and session count badges. | exp: MobileNav | dep: react, react-router-dom, ../../icon, ../tool/tools-bottom-sheet, ./spaces-bottom-sheet, ../../../utils/icons
|
||||||
- mobile-page-header.tsx | Renders a mobile-only page header with optional back navigation and custom actions. | exp: func:MobilePageHeader({ title, showBack = true, actions }: MobilePageHeaderProps), call:useNavigate, call:useMobileViewport, call:navigate | dep: react-router-dom, ../../../hooks/use-mobile-viewport, ../../icon, use-mobile-viewport hook, Icon component
|
- mobile-page-header.tsx | Renders a mobile-only page header with optional back navigation and custom actions. | exp: func:MobilePageHeader({ title, showBack = true, actions }: MobilePageHeaderProps), call:useNavigate, call:useMobileViewport, call:navigate | dep: react-router-dom, ../../../hooks/use-mobile-viewport, ../../icon, use-mobile-viewport hook, Icon component
|
||||||
- mobile-terminal-header.tsx | Renders a mobile-responsive header for a terminal interface with navigation, title, connection status, font size controls, and close actions. | exp: MobileTerminalHeader | dep: react, ../../icon, icon
|
- mobile-terminal-header.tsx | Renders a mobile-responsive header for a terminal interface with navigation, title, connection status, font size controls, and close actions. | exp: MobileTerminalHeader | dep: react, ../../icon, icon
|
||||||
- mobile-terminal-wrapper.tsx | Wraps a terminal component with mobile-specific UI including auto-hiding header, virtual keyboard handling, and special keys interface. | exp: MobileTerminalWrapper | dep: react, ../terminal/terminal, ./mobile-terminal-header, ../terminal/special-keys-strip, ../terminal/special-keys-panel, ../../../hooks/use-mobile-viewport, ../../../hooks/use-virtual-keyboard, ../../../hooks/use-auto-hide, ../../../hooks/use-special-keys
|
- mobile-terminal-wrapper.tsx | Wraps a terminal component with mobile-specific UI including auto-hiding header, virtual keyboard handling, and special keys interface. | exp: MobileTerminalWrapper | dep: react, ../terminal/terminal, ./mobile-terminal-header, ../terminal/special-keys-strip, ../terminal/special-keys-panel, ../../../hooks/use-mobile-viewport, ../../../hooks/use-virtual-keyboard, ../../../hooks/use-auto-hide, ../../../hooks/use-special-keys
|
||||||
- spaces-bottom-sheet.tsx | Renders a mobile bottom sheet navigation menu for switching between "Projects" and "Workspaces" spaces with active state highlighting | exp: SpacesBottomSheet | dep: react-router-dom, ../../icon
|
- spaces-bottom-sheet.tsx | Renders a mobile bottom sheet navigation menu for switching between "Projects" and "Workspaces" spaces with active state highlighting. | exp: SpacesBottomSheet | dep: react-router-dom, ../../icon, icon
|
||||||
## arch
|
## arch
|
||||||
Composable mobile-first component library using bottom sheets, action sheets, and floating action buttons as primary mobile interaction patterns, with feature-specific wrappers that handle mobile concerns like virtual keyboards and auto-hiding headers.
|
Compositional React component library with feature-specific mobile adaptations, using bottom sheets/action sheets for mobile-native UX patterns, and wrapper components that inject mobile-specific behaviors (auto-hiding headers, virtual keyboard handling) into existing features.
|
||||||
## tags
|
## tags
|
||||||
mobile, terminal, sheet, view, react, icon, header, renders
|
mobile, terminal, sheet, react, icon, view, header, renders
|
||||||
## symbols
|
## symbols
|
||||||
- MobileActionSheet
|
- MobileActionSheet
|
||||||
- MobilePageHeader
|
- MobilePageHeader
|
||||||
|
|||||||
@@ -67,11 +67,16 @@ export const MobileListView: React.FC<MobileListViewProps> = ({
|
|||||||
<div className="mobile-list-item-content">
|
<div className="mobile-list-item-content">
|
||||||
<div className="mobile-list-item-title">{item.title}</div>
|
<div className="mobile-list-item-title">{item.title}</div>
|
||||||
{item.subtitle && (
|
{item.subtitle && (
|
||||||
<div className="mobile-list-item-subtitle">{item.subtitle}</div>
|
<div className="mobile-list-item-subtitle">
|
||||||
|
{item.subtitle}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="mobile-list-item-actions" style={{ transform: "rotate(180deg)" }}>
|
<div
|
||||||
|
className="mobile-list-item-actions"
|
||||||
|
style={{ transform: "rotate(180deg)" }}
|
||||||
|
>
|
||||||
<Icon name="arrow-left" size="sm" />
|
<Icon name="arrow-left" size="sm" />
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -19,9 +19,21 @@ interface NavItem {
|
|||||||
|
|
||||||
const MOBILE_NAV_ITEMS: NavItem[] = [
|
const MOBILE_NAV_ITEMS: NavItem[] = [
|
||||||
{ to: "/", label: "Home", icon: "dashboard" },
|
{ to: "/", label: "Home", icon: "dashboard" },
|
||||||
|
{
|
||||||
|
to: "/spaces",
|
||||||
|
label: "Spaces",
|
||||||
|
icon: "projects",
|
||||||
|
isGroup: true,
|
||||||
|
group: "spaces",
|
||||||
|
},
|
||||||
{ to: "/sessions", label: "Sessions", icon: "terminal" },
|
{ to: "/sessions", label: "Sessions", icon: "terminal" },
|
||||||
{ to: "/spaces", label: "Spaces", icon: "projects", isGroup: true, group: "spaces" },
|
{
|
||||||
{ to: "/tools", label: "Tools", icon: "settings", isGroup: true, group: "tools" },
|
to: "/tools",
|
||||||
|
label: "Tools",
|
||||||
|
icon: "settings",
|
||||||
|
isGroup: true,
|
||||||
|
group: "tools",
|
||||||
|
},
|
||||||
{ to: "/settings", label: "Settings", icon: "settings" },
|
{ to: "/settings", label: "Settings", icon: "settings" },
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -49,10 +61,15 @@ export const MobileNav: React.FC<MobileNavProps> = ({ sessionCount }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<nav className="mobile-nav" role="navigation" aria-label="Mobile navigation">
|
<nav
|
||||||
|
className="mobile-nav"
|
||||||
|
role="navigation"
|
||||||
|
aria-label="Mobile navigation"
|
||||||
|
>
|
||||||
{MOBILE_NAV_ITEMS.map((item) => {
|
{MOBILE_NAV_ITEMS.map((item) => {
|
||||||
if (item.isGroup) {
|
if (item.isGroup) {
|
||||||
const isActive = item.group === "spaces" ? isSpacesActive : isToolsActive;
|
const isActive =
|
||||||
|
item.group === "spaces" ? isSpacesActive : isToolsActive;
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
key={item.to}
|
key={item.to}
|
||||||
|
|||||||
@@ -51,8 +51,12 @@ export const SpacesBottomSheet: React.FC<SpacesBottomSheetProps> = ({
|
|||||||
onClick={() => handleSelect(item.to)}
|
onClick={() => handleSelect(item.to)}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span className="mobile-bottom-sheet-item-label">{item.label}</span>
|
<span className="mobile-bottom-sheet-item-label">
|
||||||
{location.pathname === item.to && <Icon name="success" size="sm" />}
|
{item.label}
|
||||||
|
</span>
|
||||||
|
{location.pathname === item.to && (
|
||||||
|
<Icon name="success" size="sm" />
|
||||||
|
)}
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
dir: apps/web/src/components/features/terminal
|
dir: apps/web/src/components/features/terminal
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Provides cross-platform terminal UI components for desktop and mobile with session management, special key input, and xterm.js WebSocket connectivity.
|
Provides a cross-platform terminal emulator interface with WebSocket backend connectivity, supporting multiple sessions, special key input, and responsive desktop/mobile layouts.
|
||||||
## parent
|
## parent
|
||||||
index: apps/web/src/components/features/.pi-map.index.md
|
index: apps/web/src/components/features/.pi-map.index.md
|
||||||
map: apps/web/src/components/features/.pi-map.md
|
map: apps/web/src/components/features/.pi-map.md
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ dir: apps/web/src/components/features/terminal
|
|||||||
index: apps/web/src/components/features/terminal/.pi-map.index.md
|
index: apps/web/src/components/features/terminal/.pi-map.index.md
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Provides cross-platform terminal UI components for desktop and mobile with session management, special key input, and xterm.js WebSocket connectivity.
|
Provides a cross-platform terminal emulator interface with WebSocket backend connectivity, supporting multiple sessions, special key input, and responsive desktop/mobile layouts.
|
||||||
## files
|
## files
|
||||||
- DesktopTerminalView.tsx | Renders a desktop-optimized terminal view with session tabs, fullscreen mode, font controls, and reset confirmation dialog | exp: DesktopTerminalView | dep: react, ./terminal, ./terminal-session-tabs, ../../../api/terminal, React, TerminalComponent, TerminalSessionTabs, TerminalSession type
|
- DesktopTerminalView.tsx | Renders a desktop-optimized terminal view with session tabs, fullscreen mode, font controls, and reset confirmation dialog | exp: DesktopTerminalView | dep: react, ./terminal, ./terminal-session-tabs, ../../../api/terminal, React, TerminalComponent, TerminalSessionTabs, TerminalSession type
|
||||||
- MobileTerminalView.tsx | Renders a mobile-optimized terminal interface with toolbar, session tabs, terminal output, and special keys input controls. | exp: MobileTerminalView | dep: react, ./terminal, ./terminal-session-tabs, ../../icon, ./special-keys-strip, ./special-keys-panel, ../../../hooks/use-special-keys, ../../../api/terminal
|
- MobileTerminalView.tsx | Renders a mobile-optimized terminal interface with toolbar, session tabs, terminal output, and special keys input controls. | exp: MobileTerminalView | dep: react, ./terminal, ./terminal-session-tabs, ../../icon, ./special-keys-strip, ./special-keys-panel, ../../../hooks/use-special-keys, ../../../api/terminal
|
||||||
@@ -12,9 +12,9 @@ Provides cross-platform terminal UI components for desktop and mobile with sessi
|
|||||||
- special-keys-strip.tsx | Renders a strip of buttons for sending special keyboard keys (Esc, Tab, arrows, etc.) with optional modifier support for a terminal interface. | exp: SpecialKeysStrip | dep: react, ../../../hooks/use-special-keys, React, use-special-keys hook
|
- special-keys-strip.tsx | Renders a strip of buttons for sending special keyboard keys (Esc, Tab, arrows, etc.) with optional modifier support for a terminal interface. | exp: SpecialKeysStrip | dep: react, ../../../hooks/use-special-keys, React, use-special-keys hook
|
||||||
- terminal-session-tabs.test.tsx | Tests a React component that renders interactive terminal session tabs with selection, close confirmation, renaming, creation limits, and status indicators. | dep: @testing-library/react, vitest, ./terminal-session-tabs
|
- terminal-session-tabs.test.tsx | Tests a React component that renders interactive terminal session tabs with selection, close confirmation, renaming, creation limits, and status indicators. | dep: @testing-library/react, vitest, ./terminal-session-tabs
|
||||||
- terminal-session-tabs.tsx | Renders a tabbed interface for managing multiple terminal sessions with selection, creation, renaming, and close confirmation features. | exp: TerminalSessionInfo, TerminalSessionTabsProps, TerminalSessionTabs | dep: react, React
|
- terminal-session-tabs.tsx | Renders a tabbed interface for managing multiple terminal sessions with selection, creation, renaming, and close confirmation features. | exp: TerminalSessionInfo, TerminalSessionTabsProps, TerminalSessionTabs | dep: react, React
|
||||||
- terminal.tsx | React component that renders an interactive xterm.js terminal with WebSocket connectivity, mobile touch support, flow control, heartbeat monitoring, and reconnection logic. | exp: TerminalProps, TerminalRef, TerminalComponent | dep: react, xterm, xterm-addon-fit, xterm-addon-web-links, xterm/css/xterm.css, ../../../hooks/use-special-keys, React, use-special-keys hook
|
- terminal.tsx | A React component that renders an interactive terminal emulator using xterm.js, connecting to a WebSocket backend with features like mobile touch scrolling, font resizing, flow control, heartbeat monitoring, and automatic reconnection. | exp: TerminalProps, TerminalRef, TerminalComponent | dep: react, xterm, xterm-addon-fit, xterm-addon-web-links, xterm/css/xterm.css, ../../../hooks/use-special-keys
|
||||||
## arch
|
## arch
|
||||||
Component-based architecture with platform-specific view variants (Desktop/Mobile), shared session tabs state management, modular special key input panels, and a core terminal component handling WebSocket lifecycle with heartbeat/reconnection logic.
|
Component-based architecture with platform-specific view variants (Desktop/Mobile), compound component pattern for terminal subsystems (tabs, special keys, xterm.js integration), and WebSocket-based real-time communication with reconnection and heartbeat monitoring.
|
||||||
## tags
|
## tags
|
||||||
terminal, special, keys, session, react, tabs, view, renders
|
terminal, special, keys, session, react, tabs, view, renders
|
||||||
## symbols
|
## symbols
|
||||||
|
|||||||
@@ -355,13 +355,41 @@ export const TerminalComponent = React.forwardRef<TerminalRef, TerminalProps>(
|
|||||||
// In normal mode xterm.js has a scrollable viewport; in alternate
|
// In normal mode xterm.js has a scrollable viewport; in alternate
|
||||||
// screen (tmux/vim) there is no scrollback and the only way to
|
// screen (tmux/vim) there is no scrollback and the only way to
|
||||||
// scroll is to send mouse-wheel protocol sequences to the
|
// scroll is to send mouse-wheel protocol sequences to the
|
||||||
// application. We detect which situation we're in by checking
|
// application. We detect the active buffer by reference equality
|
||||||
// whether the viewport has scrollable height.
|
// (term.buffer.active === term.buffer.alternate) because the
|
||||||
|
// `type` string can be unreliable in some xterm.js versions.
|
||||||
let touchCleanup: (() => void) | undefined;
|
let touchCleanup: (() => void) | undefined;
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
let startY = 0;
|
let startY = 0;
|
||||||
let startX = 0;
|
let startX = 0;
|
||||||
let isScrolling = false;
|
let isScrolling = false;
|
||||||
|
let debugOverlay: HTMLDivElement | null = null;
|
||||||
|
const showDebug = (msg: string) => {
|
||||||
|
if (!debugOverlay) {
|
||||||
|
debugOverlay = document.createElement("div");
|
||||||
|
debugOverlay.style.position = "fixed";
|
||||||
|
debugOverlay.style.bottom = "120px";
|
||||||
|
debugOverlay.style.left = "8px";
|
||||||
|
debugOverlay.style.right = "8px";
|
||||||
|
debugOverlay.style.zIndex = "9999";
|
||||||
|
debugOverlay.style.background = "rgba(0,0,0,0.8)";
|
||||||
|
debugOverlay.style.color = "#0f0";
|
||||||
|
debugOverlay.style.fontFamily = "monospace";
|
||||||
|
debugOverlay.style.fontSize = "11px";
|
||||||
|
debugOverlay.style.padding = "8px";
|
||||||
|
debugOverlay.style.borderRadius = "6px";
|
||||||
|
debugOverlay.style.pointerEvents = "none";
|
||||||
|
debugOverlay.style.whiteSpace = "pre-wrap";
|
||||||
|
debugOverlay.style.maxHeight = "120px";
|
||||||
|
debugOverlay.style.overflow = "auto";
|
||||||
|
document.body.appendChild(debugOverlay);
|
||||||
|
}
|
||||||
|
const line = `${new Date().toLocaleTimeString()} ${msg}`;
|
||||||
|
debugOverlay.textContent =
|
||||||
|
line +
|
||||||
|
"\n" +
|
||||||
|
debugOverlay.textContent?.split("\n").slice(0, 8).join("\n");
|
||||||
|
};
|
||||||
|
|
||||||
const onTouchStart = (e: TouchEvent) => {
|
const onTouchStart = (e: TouchEvent) => {
|
||||||
if (e.touches.length === 1) {
|
if (e.touches.length === 1) {
|
||||||
@@ -375,46 +403,49 @@ export const TerminalComponent = React.forwardRef<TerminalRef, TerminalProps>(
|
|||||||
const touch = e.touches[0];
|
const touch = e.touches[0];
|
||||||
const deltaY = startY - touch.clientY;
|
const deltaY = startY - touch.clientY;
|
||||||
const deltaX = Math.abs(startX - touch.clientX);
|
const deltaX = Math.abs(startX - touch.clientX);
|
||||||
|
showDebug(`move dy=${deltaY.toFixed(0)} dx=${deltaX.toFixed(0)} scrolling=${isScrolling}`);
|
||||||
|
|
||||||
|
// Decide early whether this is a vertical scroll gesture.
|
||||||
if (!isScrolling) {
|
if (!isScrolling) {
|
||||||
if (Math.abs(deltaY) > deltaX && Math.abs(deltaY) > 4) {
|
if (Math.abs(deltaY) > deltaX && Math.abs(deltaY) > 2) {
|
||||||
isScrolling = true;
|
isScrolling = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isScrolling) {
|
if (!isScrolling) return;
|
||||||
e.preventDefault();
|
|
||||||
const viewport = container.querySelector(
|
|
||||||
".xterm-viewport",
|
|
||||||
) as HTMLElement | null;
|
|
||||||
if (!viewport) return;
|
|
||||||
|
|
||||||
// If the viewport is scrollable, scroll it directly.
|
// Take over the gesture so the browser never scrolls the
|
||||||
// Otherwise we are in alternate screen (tmux/vim) and must
|
// page or the terminal canvas. We synthesize wheel events
|
||||||
// send SGR 1006 mouse-wheel protocol data.
|
// and dispatch them into xterm.js, which already handles
|
||||||
const hasScrollback = viewport.scrollHeight > viewport.clientHeight;
|
// both normal buffer scrolling and alternate-screen apps
|
||||||
if (hasScrollback) {
|
// (tmux/vim) correctly.
|
||||||
viewport.scrollTop += deltaY;
|
e.preventDefault();
|
||||||
} else {
|
|
||||||
const ws = wsRef.current;
|
const target = container.querySelector(".xterm-viewport") as
|
||||||
if (ws?.readyState === WebSocket.OPEN && termRef.current) {
|
| HTMLElement
|
||||||
// Use the cursor position as the wheel location so
|
| null;
|
||||||
// tmux knows which pane to scroll.
|
if (target) {
|
||||||
const buf = termRef.current.buffer.active;
|
showDebug(`dispatch wheel deltaY=${deltaY.toFixed(0)}`);
|
||||||
const col = buf.cursorX + 1;
|
const wheel = new WheelEvent("wheel", {
|
||||||
const row = buf.cursorY + 1;
|
deltaY,
|
||||||
// SGR 1006: 64 = wheel-up, 65 = wheel-down
|
deltaX: 0,
|
||||||
const btn = deltaY > 0 ? 64 : 65;
|
deltaZ: 0,
|
||||||
ws.send(`\x1b[<${btn};${col};${row}M`);
|
clientX: touch.clientX,
|
||||||
}
|
clientY: touch.clientY,
|
||||||
|
screenX: touch.screenX,
|
||||||
|
screenY: touch.screenY,
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true,
|
||||||
|
});
|
||||||
|
target.dispatchEvent(wheel);
|
||||||
}
|
}
|
||||||
startY = touch.clientY;
|
startY = touch.clientY;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
const onTouchEnd = () => {
|
const onTouchEnd = () => {
|
||||||
isScrolling = false;
|
isScrolling = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
container.addEventListener("touchstart", onTouchStart, {
|
container.addEventListener("touchstart", onTouchStart, {
|
||||||
passive: true,
|
passive: false,
|
||||||
capture: true,
|
capture: true,
|
||||||
});
|
});
|
||||||
container.addEventListener("touchmove", onTouchMove, {
|
container.addEventListener("touchmove", onTouchMove, {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
dir: apps/web/src/components/features/workspace
|
dir: apps/web/src/components/features/workspace
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Provides React UI components for workspace management, navigation, and detail views in a web-based development environment.
|
Provides the complete UI component suite for workspace management, including creation, detail viewing, file editing, Git operations, tool management, and settings.
|
||||||
## parent
|
## parent
|
||||||
index: apps/web/src/components/features/.pi-map.index.md
|
index: apps/web/src/components/features/.pi-map.index.md
|
||||||
map: apps/web/src/components/features/.pi-map.md
|
map: apps/web/src/components/features/.pi-map.md
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ dir: apps/web/src/components/features/workspace
|
|||||||
index: apps/web/src/components/features/workspace/.pi-map.index.md
|
index: apps/web/src/components/features/workspace/.pi-map.index.md
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Provides React UI components for workspace management, navigation, and detail views in a web-based development environment.
|
Provides the complete UI component suite for workspace management, including creation, detail viewing, file editing, Git operations, tool management, and settings.
|
||||||
## files
|
## files
|
||||||
- workspace-card.tsx | React card component that displays workspace information with status, metadata, and action buttons | exp: WorkspaceCardProps, func:WorkspaceCard({ workspace, loading = false, onStartTool, onSync, onDelete, }: WorkspaceCardProps), call:onStartTool, call:onSync, call:onDelete | dep: react-router-dom, ../../icon, ./workspace-instance-chips, ../../../types/workspace
|
- workspace-card.tsx | React component that renders a card displaying workspace information with status, metadata, and action buttons. | exp: WorkspaceCardProps, func:WorkspaceCard({ workspace, loading = false, onStartTool, onSync, onDelete, }: WorkspaceCardProps), call:onStartTool, call:onSync, call:onDelete | dep: react-router-dom, ../../icon, ./workspace-instance-chips, ../../../types/workspace
|
||||||
- workspace-create-form.tsx | React form component for creating workspaces with cascading project/repository/branch selectors and support for both contextual and standalone modes | exp: WorkspaceCreateFormProps, func:WorkspaceCreateForm({ onSubmit, onCancel, defaultProjectId, defaultRepoId, }: WorkspaceCreateFormProps), call:Boolean, call:useState, call:useGitRepo, call:useEffect, call:git.branches.includes, call:setSelectedBranch, call:setIsNewBranch, call:useCallback, call:listProjects, call:setProjects, call:setSelectedProject, call:setError, call:setFetchingProjects, call:loadProjects, call:setRepos, call:setSelectedRepo, call:listRepositories, call:loadRepos, call:setNewBranchName, call:e.preventDefault, call:name.trim, call:newBranchName.trim, call:setSubmitting, call:createWorkspaceTopLevel, call:onSubmit, call:projects.map, call:repos.map, call:setName, call:handleBranchChange, call:git.branches.map | dep: react, ../../icon, ../../../api/projects, ../../../api/git-repositories, ../../../api/workspaces, ../../../hooks/use-git-repo, ../../../types, icon, api/projects, api/git-repositories, api/workspaces, hooks/use-git-repo, types
|
- workspace-create-form.tsx | React form component for creating workspaces with cascading project/repository/branch selectors and support for both contextual and standalone modes | exp: WorkspaceCreateFormProps, func:WorkspaceCreateForm({ onSubmit, onCancel, defaultProjectId, defaultRepoId, }: WorkspaceCreateFormProps), call:Boolean, call:useState, call:useGitRepo, call:useEffect, call:git.branches.includes, call:setSelectedBranch, call:setIsNewBranch, call:useCallback, call:listProjects, call:setProjects, call:setSelectedProject, call:setError, call:setFetchingProjects, call:loadProjects, call:setRepos, call:setSelectedRepo, call:listRepositories, call:loadRepos, call:setNewBranchName, call:e.preventDefault, call:name.trim, call:newBranchName.trim, call:setSubmitting, call:createWorkspaceTopLevel, call:onSubmit, call:projects.map, call:repos.map, call:setName, call:handleBranchChange, call:git.branches.map | dep: react, ../../icon, ../../../api/projects, ../../../api/git-repositories, ../../../api/workspaces, ../../../hooks/use-git-repo, ../../../types, icon, api/projects, api/git-repositories, api/workspaces, hooks/use-git-repo, types
|
||||||
- workspace-detail-header.tsx | Renders a header component for a workspace detail page showing breadcrumb navigation and branch information. | exp: WorkspaceDetailHeaderProps, func:WorkspaceDetailHeader({ workspace, }: WorkspaceDetailHeaderProps) | dep: ../../icon, react
|
- workspace-detail-header.tsx | Renders a header component for a workspace detail page showing breadcrumb navigation and branch information. | exp: WorkspaceDetailHeaderProps, func:WorkspaceDetailHeader({ workspace, }: WorkspaceDetailHeaderProps) | dep: ../../icon, react
|
||||||
- workspace-file-panel.tsx | Renders a file browser and editor panel with Git integration for a workspace detail page. | exp: func:WorkspaceFilePanel({ workspaceId }: WorkspaceFilePanelProps), call:useWorkspaceFiles, call:useWorkspaceGit, call:useState, call:setSelectedPath, call:setIsEditing, call:setEditContent, call:navigateTo, call:loadFile, call:currentPath.split("/").slice(0, -1).join, call:saveFile, call:setCommitMessage, call:commit, call:entries.map, call:handleSelect | dep: react, ../../icon, ../../../hooks/use-workspace-files, ../../../hooks/use-workspace-git, ../../../api/workspace-files
|
- workspace-file-panel.tsx | Renders a file browser and editor panel with Git integration for a workspace detail page. | exp: func:WorkspaceFilePanel({ workspaceId }: WorkspaceFilePanelProps), call:useWorkspaceFiles, call:useWorkspaceGit, call:useState, call:setSelectedPath, call:setIsEditing, call:setEditContent, call:navigateTo, call:loadFile, call:currentPath.split("/").slice(0, -1).join, call:saveFile, call:setCommitMessage, call:commit, call:entries.map, call:handleSelect | dep: react, ../../icon, ../../../hooks/use-workspace-files, ../../../hooks/use-workspace-git, ../../../api/workspace-files
|
||||||
@@ -17,7 +17,7 @@ Provides React UI components for workspace management, navigation, and detail vi
|
|||||||
- workspace-tab-bar.tsx | Renders desktop and mobile tab bar components for workspace navigation with files, git, tools, and settings tabs. | exp: WorkspaceTab, func:WorkspaceTabBar({ active, onChange }: WorkspaceTabBarProps), call:TABS.map, call:onChange, func:WorkspaceMobileTabBar({ active, onChange, }: WorkspaceTabBarProps), call:TABS.map, call:onChange | dep: ../../icon, react
|
- workspace-tab-bar.tsx | Renders desktop and mobile tab bar components for workspace navigation with files, git, tools, and settings tabs. | exp: WorkspaceTab, func:WorkspaceTabBar({ active, onChange }: WorkspaceTabBarProps), call:TABS.map, call:onChange, func:WorkspaceMobileTabBar({ active, onChange, }: WorkspaceTabBarProps), call:TABS.map, call:onChange | dep: ../../icon, react
|
||||||
- workspace-tools-panel.tsx | Renders a tools management panel for a workspace that displays running tool instances and allows starting new tools via a modal | exp: func:WorkspaceToolsPanel({ workspace }: WorkspaceToolsPanelProps), call:useWorkspaceInstances, call:useState, call:setShowModal, call:instances.map, call:e.stopPropagation, call:refresh | dep: react, ../../icon, ../tool/tool-starter, ../../../hooks/use-workspace-instances, ../../../types/workspace, icon, tool-starter, use-workspace-instances, workspace types
|
- workspace-tools-panel.tsx | Renders a tools management panel for a workspace that displays running tool instances and allows starting new tools via a modal | exp: func:WorkspaceToolsPanel({ workspace }: WorkspaceToolsPanelProps), call:useWorkspaceInstances, call:useState, call:setShowModal, call:instances.map, call:e.stopPropagation, call:refresh | dep: react, ../../icon, ../tool/tool-starter, ../../../hooks/use-workspace-instances, ../../../types/workspace, icon, tool-starter, use-workspace-instances, workspace types
|
||||||
## arch
|
## arch
|
||||||
Feature-based component organization with page-specific composite components (header/detail/settings) and reusable atomic pieces (cards, chips, forms), following a panel/tab architecture for workspace detail layout.
|
Feature-based component organization with compound page pattern (header/tab-bar/panels), form abstraction for creation, and modal-driven tool management with responsive mobile/desktop tab navigation.
|
||||||
## tags
|
## tags
|
||||||
workspace, call:set, call:use, panel, git, branch, react, call:on
|
workspace, call:set, call:use, panel, git, branch, react, call:on
|
||||||
## symbols
|
## symbols
|
||||||
|
|||||||
@@ -35,16 +35,19 @@ export function WorkspaceCard({
|
|||||||
className="workspace-title-link"
|
className="workspace-title-link"
|
||||||
>
|
>
|
||||||
<div className="workspace-title-stack">
|
<div className="workspace-title-stack">
|
||||||
<span className="workspace-project-name">
|
<div className="workspace-title-row">
|
||||||
{workspace.project_name}
|
|
||||||
</span>
|
|
||||||
<h4 className="workspace-name">{workspace.name}</h4>
|
<h4 className="workspace-name">{workspace.name}</h4>
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
<span className={`status-badge ${statusClass}`}>
|
<span className={`status-badge ${statusClass}`}>
|
||||||
{workspace.status}
|
{workspace.status}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<span className="workspace-project-name">
|
||||||
|
<Icon name="projects" size="sm" />
|
||||||
|
{workspace.project_name}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="workspace-card-body">
|
<div className="workspace-card-body">
|
||||||
<div className="workspace-meta-row">
|
<div className="workspace-meta-row">
|
||||||
|
|||||||
@@ -182,7 +182,9 @@ export const ProjectsPage = () => {
|
|||||||
)}
|
)}
|
||||||
<div className="mobile-list-item-chips">
|
<div className="mobile-list-item-chips">
|
||||||
{(project.repositories?.length ?? 0) === 0 ? (
|
{(project.repositories?.length ?? 0) === 0 ? (
|
||||||
<span className="mobile-list-item-chip muted">No repositories</span>
|
<span className="mobile-list-item-chip muted">
|
||||||
|
No repositories
|
||||||
|
</span>
|
||||||
) : (
|
) : (
|
||||||
project.repositories.map((repo) => (
|
project.repositories.map((repo) => (
|
||||||
<span key={repo.id} className="mobile-list-item-chip">
|
<span key={repo.id} className="mobile-list-item-chip">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
dir: apps/web/src/styles
|
dir: apps/web/src/styles
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Houses the complete CSS styling system for a web application, including design tokens, global styles, syntax highlighting themes, and utility classes.
|
Provides the complete visual design system and styling foundation for the web application, encompassing global styles, design tokens, utility classes, and component-specific styles.
|
||||||
## parent
|
## parent
|
||||||
index: apps/web/src/.pi-map.index.md
|
index: apps/web/src/.pi-map.index.md
|
||||||
map: apps/web/src/.pi-map.md
|
map: apps/web/src/.pi-map.md
|
||||||
|
|||||||
@@ -4,16 +4,16 @@ dir: apps/web/src/styles
|
|||||||
index: apps/web/src/styles/.pi-map.index.md
|
index: apps/web/src/styles/.pi-map.index.md
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Houses the complete CSS styling system for a web application, including design tokens, global styles, syntax highlighting themes, and utility classes.
|
Provides the complete visual design system and styling foundation for the web application, encompassing global styles, design tokens, utility classes, and component-specific styles.
|
||||||
## files
|
## files
|
||||||
- global.css | Defines global CSS styles for a web application shell layout, navigation, cards, forms, dialogs, settings pages, and responsive design patterns. | dep: CSS custom properties (CSS variables: --border, --panel, --brand, --muted, --ink, --bg, --danger, --success, --warning, --font-size-xs, --font-size-sm, --space-2, --space-3, --space-4, --space-5)
|
- global.css | Defines global CSS styles for a web application shell layout, navigation, cards, forms, dialogs, settings pages, and responsive design patterns. | dep: CSS custom properties (CSS variables: --border, --panel, --brand, --muted, --ink, --bg, --danger, --success, --warning, --font-size-xs, --font-size-sm, --space-2, --space-3, --space-4, --space-5)
|
||||||
- syntax-highlight.css | Stylesheet for a syntax highlighting component with toolbar, line numbers, code display, and Prism.js theme integration | dep: Prism.js
|
- syntax-highlight.css | Stylesheet for a syntax highlighting component with toolbar, line numbers, code display, and Prism.js theme integration | dep: Prism.js
|
||||||
- tokens.css | Defines a comprehensive CSS design token system with light/dark themes, spacing scales, breakpoints, and fluid typography for a web application.
|
- tokens.css | Defines a comprehensive CSS design token system with light/dark themes, spacing scales, breakpoints, and fluid typography for a web application.
|
||||||
- utilities.css | Provides a comprehensive responsive CSS utility system with terminal-specific styling, mobile adaptations, and component patterns for a web application. | dep: CSS custom properties (var(--space-*), var(--border), var(--bg), var(--text), var(--brand), var(--muted), var(--success), var(--danger), var(--danger-light)), xterm.js (terminal integration)
|
- utilities.css | Provides responsive CSS utility classes and component-specific styles for a web application featuring terminals, dialogs, tables, forms, and navigation with mobile-first breakpoints | dep: CSS custom properties (variables like --space-*, --border, --bg, --brand, --muted, --success, --danger, --text-xs, --text-sm), xterm.js (terminal library)
|
||||||
## arch
|
## arch
|
||||||
Token-driven CSS architecture using CSS custom properties for themeable light/dark modes, utility-first responsive patterns, and component-scoped stylesheets with Prism.js integration for syntax highlighting.
|
CSS custom properties (variables) based theming system with light/dark mode support, mobile-first responsive breakpoints, fluid typography scales, utility-first class patterns, and modular separation of concerns across tokens, utilities, global layouts, and component-specific styles.
|
||||||
## tags
|
## tags
|
||||||
var(, space, global, css, web, application, syntax, defines
|
space, global, css, web, application, syntax, defines, styles
|
||||||
## symbols
|
## symbols
|
||||||
-
|
-
|
||||||
## workflows
|
## workflows
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
dir: apps/web/src/styles/pages
|
dir: apps/web/src/styles/pages
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Package containing page-specific CSS stylesheets for individual web application views
|
Contains page-specific CSS stylesheets for individual application views in the web frontend, providing scoped styling for distinct feature areas.
|
||||||
## parent
|
## parent
|
||||||
index: apps/web/src/styles/.pi-map.index.md
|
index: apps/web/src/styles/.pi-map.index.md
|
||||||
map: apps/web/src/styles/.pi-map.md
|
map: apps/web/src/styles/.pi-map.md
|
||||||
|
|||||||
@@ -4,18 +4,18 @@ dir: apps/web/src/styles/pages
|
|||||||
index: apps/web/src/styles/pages/.pi-map.index.md
|
index: apps/web/src/styles/pages/.pi-map.index.md
|
||||||
|
|
||||||
## role
|
## role
|
||||||
Package containing page-specific CSS stylesheets for individual web application views
|
Contains page-specific CSS stylesheets for individual application views in the web frontend, providing scoped styling for distinct feature areas.
|
||||||
## files
|
## files
|
||||||
- git-history.css | Stylesheet for a Git history visualization page with commit list, branch selector, and detail panel layout | dep: CSS custom properties (var(--border), var(--panel), var(--ink), var(--brand), var(--muted))
|
- git-history.css | Stylesheet for a Git history visualization page with commit list, branch selector, and detail panel layout | dep: CSS custom properties (var(--border), var(--panel), var(--ink), var(--brand), var(--muted))
|
||||||
- projects.css | Stylesheet for a projects page UI featuring expandable project toggles, repository listings, workspace grids, and repository creation radio controls. | dep: CSS custom properties (variables)
|
- projects.css | Stylesheet for a projects page UI featuring expandable project toggles, repository listings, workspace grids, and repository creation radio controls. | dep: CSS custom properties (variables)
|
||||||
- sessions.css | Stylesheet for session management UI components including cards, dropdowns, forms, and responsive mobile layouts. | dep: CSS custom properties/variables (var(--border), var(--panel), var(--text), var(--space-*), var(--danger), var(--color-border))
|
- sessions.css | Stylesheet for session management UI components including cards, dropdowns, forms, and responsive mobile layouts. | dep: CSS custom properties/variables (var(--border), var(--panel), var(--text), var(--space-*), var(--danger), var(--color-border))
|
||||||
- ssh-keys.css | Styles a responsive SSH key list component that stacks vertically on mobile and switches to horizontal layout on larger screens | dep: CSS custom properties (var(--space-3), var(--space-2), var(--space-4), var(--bg), var(--border))
|
- ssh-keys.css | Styles a responsive SSH key list component that stacks vertically on mobile and switches to horizontal layout on larger screens | dep: CSS custom properties (var(--space-3), var(--space-2), var(--space-4), var(--bg), var(--border))
|
||||||
- workspace-detail.css | Stylesheet for a workspace detail page with tabbed interface including files, git, tools, and settings views, plus a workspace creation form | dep: CSS custom properties (variables for colors, spacing, typography)
|
- workspace-detail.css | Stylesheet for a workspace detail page with tabbed interface including files, git, tools, and settings views, plus a workspace creation form | dep: CSS custom properties (variables for colors, spacing, typography)
|
||||||
- workspaces.css | Styles a workspaces page with responsive card grid layout, status badges, and instance chips | dep: CSS custom properties (var(--space-*), var(--border), var(--brand), var(--panel), var(--ink), var(--muted), var(--bg), var(--success), var(--warning), var(--danger), var(--font-size-*))
|
- workspaces.css | Stylesheet for a workspaces management page featuring responsive grid layout, workspace cards with status badges, instance chips, and mobile adaptations. | dep: CSS custom properties (design tokens: --space-*, --border, --panel, --brand, --ink, --muted, --bg, --success, --warning, --danger, --font-size-*)
|
||||||
## arch
|
## arch
|
||||||
Modular CSS architecture with dedicated stylesheets per page domain, featuring responsive design patterns, component-based styling, and mobile-first breakpoint strategies
|
Modular CSS architecture with page-level style separation, responsive design patterns using media queries for mobile adaptation, and component-scoped styling organized by feature domain rather than shared component library.
|
||||||
## tags
|
## tags
|
||||||
var(, workspace, space, stylesheet, git, page, detail, history
|
var(, workspace, stylesheet, space, git, page, detail, history
|
||||||
## symbols
|
## symbols
|
||||||
-
|
-
|
||||||
## workflows
|
## workflows
|
||||||
|
|||||||
@@ -40,7 +40,6 @@
|
|||||||
.workspace-card-top {
|
.workspace-card-top {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
justify-content: space-between;
|
|
||||||
gap: var(--space-3);
|
gap: var(--space-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,15 +62,11 @@
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workspace-project-name {
|
.workspace-title-row {
|
||||||
font-size: var(--font-size-sm);
|
display: flex;
|
||||||
font-weight: 500;
|
align-items: center;
|
||||||
color: var(--muted);
|
gap: var(--space-2);
|
||||||
text-transform: uppercase;
|
min-width: 0;
|
||||||
letter-spacing: 0.04em;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.workspace-name {
|
.workspace-name {
|
||||||
@@ -82,6 +77,24 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspace-project-name {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-1);
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--muted);
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspace-project-name .icon {
|
||||||
|
color: var(--brand);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Body: meta row + instance chips */
|
/* Body: meta row + instance chips */
|
||||||
|
|||||||
@@ -553,6 +553,12 @@ a.nav-item,
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Let xterm.js's own viewport handle touch; we only lock the outer page */
|
||||||
|
.terminal-container .xterm-viewport {
|
||||||
|
touch-action: auto;
|
||||||
|
overscroll-behavior: auto;
|
||||||
|
}
|
||||||
|
|
||||||
/* xterm.js manages its own positioning and sizing */
|
/* xterm.js manages its own positioning and sizing */
|
||||||
|
|
||||||
.terminal-container canvas {
|
.terminal-container canvas {
|
||||||
@@ -566,6 +572,11 @@ a.nav-item,
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.terminal-wrapper.mobile {
|
||||||
|
touch-action: none;
|
||||||
|
overscroll-behavior: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* Ensure xterm viewport fills container properly */
|
/* Ensure xterm viewport fills container properly */
|
||||||
/* Responsive terminal */
|
/* Responsive terminal */
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767px) {
|
||||||
@@ -855,17 +866,23 @@ a.nav-item,
|
|||||||
Mobile Terminal Overlay
|
Mobile Terminal Overlay
|
||||||
============================================ */
|
============================================ */
|
||||||
|
|
||||||
/* Mobile terminal page — no padding, terminal fills viewport */
|
/* Mobile terminal page — no padding, terminal fills viewport, locked in place */
|
||||||
.terminal-page.mobile {
|
.terminal-page.mobile {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
height: 100dvh;
|
height: 100dvh;
|
||||||
position: relative;
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
touch-action: none;
|
||||||
|
overscroll-behavior: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Overlay status bar — floats over terminal, never resizes it */
|
/* Overlay status bar — floats over terminal; only its buttons consume pointer events */
|
||||||
.mobile-terminal-overlay {
|
.mobile-terminal-overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -874,11 +891,21 @@ a.nav-item,
|
|||||||
z-index: 100;
|
z-index: 100;
|
||||||
background: #2d2d2d;
|
background: #2d2d2d;
|
||||||
border-bottom: 1px solid #3e3e3e;
|
border-bottom: 1px solid #3e3e3e;
|
||||||
|
pointer-events: none;
|
||||||
transition:
|
transition:
|
||||||
transform 0.3s ease,
|
transform 0.3s ease,
|
||||||
opacity 0.3s ease;
|
opacity 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile-terminal-overlay.visible {
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-terminal-overlay > *,
|
||||||
|
.mobile-terminal-overlay-tabs {
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.mobile-terminal-overlay.hidden {
|
.mobile-terminal-overlay.hidden {
|
||||||
transform: translateY(-100%);
|
transform: translateY(-100%);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@@ -978,13 +1005,15 @@ a.nav-item,
|
|||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Terminal content — always fills full viewport on mobile */
|
/* Terminal content — always fills full viewport on mobile, locked against page scroll */
|
||||||
.terminal-page-content.mobile-full {
|
.terminal-page-content.mobile-full {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
touch-action: none;
|
||||||
|
overscroll-behavior: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mobile fullscreen */
|
/* Mobile fullscreen */
|
||||||
|
|||||||
Reference in New Issue
Block a user