chore: patch project maps after stale backend test cleanup

Regenerate .pi-map*.md artifacts for source changes in:
- apps/api/src/api/tool/tool_types_validation.py
- apps/api/src/schemas/tool/tool_type.py
- apps/api/tests/integration/test_tool_types_api_extended.py
- and all affected test files from backend-frontend refactoring cleanup
This commit is contained in:
Developer
2026-06-12 20:36:31 +00:00
parent c6073fe9d2
commit 7ef8b0eb36
188 changed files with 348 additions and 361 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api
## role
Backend API service that provides a self-hosted FastAPI server for managing development projects, git repositories, and containerized tools via Docker.
Self-hosted FastAPI backend API that manages projects, git repositories, and development tools through Docker container orchestration.
## parent
index: apps/.pi-map.index.md
map: apps/.pi-map.md
+2 -2
View File
@@ -4,7 +4,7 @@ dir: apps/api
index: apps/api/.pi-map.index.md
## role
Backend API service that provides a self-hosted FastAPI server for managing development projects, git repositories, and containerized tools via Docker.
Self-hosted FastAPI backend API that manages projects, git repositories, and development tools through Docker container orchestration.
## files
- .dockerignore | Specifies files and directories to exclude from Docker build context to reduce image size and avoid copying unnecessary files into containers. | dep: Docker
- Dockerfile | Multi-stage Docker build for a Python application with Docker socket access, Cloudflare tunneling, and database dependency waiting | dep: python:3.11-slim, gcc, libpq-dev, docker-ce-cli, docker-compose-plugin, cloudflared, uvicorn, pyproject.toml dependencies
@@ -14,7 +14,7 @@ Backend API service that provides a self-hosted FastAPI server for managing deve
- 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
## arch
Modern Python async architecture using FastAPI with SQLAlchemy/alembic for PostgreSQL, uv for dependency management, multi-stage Docker builds with Cloudflare tunneling, and health-check orchestration for database readiness.
Async Python backend using FastAPI with PostgreSQL (asyncpg), Alembic migrations, multi-stage Docker deployment with Cloudflare tunneling, uv package management, and containerized service coordination with database dependency waiting.
## tags
docker, alembic, python, database, fastapi, postgresql, asyncpg, uvicorn
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/alembic
## role
Database migration tooling that manages schema versioning and changes for the API's PostgreSQL database using Alembic with async SQLAlchemy.
Database migration infrastructure for managing schema evolution with async SQLAlchemy support.
## parent
index: apps/api/.pi-map.index.md
map: apps/api/.pi-map.md
+12 -5
View File
@@ -4,16 +4,23 @@ dir: apps/api/alembic
index: apps/api/alembic/.pi-map.index.md
## role
Database migration tooling that manages schema versioning and changes for the API's PostgreSQL database using Alembic with async SQLAlchemy.
Database migration infrastructure for managing schema evolution with async SQLAlchemy support.
## files
- env.py | Configures Alembic database migration environment with async SQLAlchemy support for a project. | dep: alembic, sqlalchemy, sqlalchemy.ext.asyncio, logging.config, asyncio, src.config, src.models
- env.py | Configures Alembic database migration environment with async SQLAlchemy support for a project. | exp: func:run_migrations_offline() → None, call:context.configure, call:context.begin_transaction, call:context.run_migrations, func:do_run_migrations(connection: Connection) → None, call:context.configure, call:context.begin_transaction, call:context.run_migrations, func:run_async_migrations() → None, call:async_engine_from_config, call:config.get_section, call:connectable.connect, call:connection.run_sync, call:connectable.dispose, func:run_migrations_online() → None, call:asyncio.run, call:run_async_migrations | dep: logging.config, alembic, sqlalchemy, sqlalchemy.engine, sqlalchemy.ext.asyncio, src.config, src.models, asyncio
- script.py.mako | Alembic database migration script template that generates upgrade/downgrade functions for SQLAlchemy schema migrations | dep: alembic, sqlalchemy
## arch
Template-driven migration pattern using Alembic's declarative configuration with async engine setup, environment context management, and auto-generated revision scripts with upgrade/downgrade function pairs.
Alembic migration framework with async SQLAlchemy engine configuration and templated revision scripts.
## tags
sqlalchemy, alembic, database, migration, asyncio, config, src, env
migrations, run, sqlalchemy, async, alembic, call:context.configure, call:context.begin, transaction
## symbols
-
- run_migrations_offline
- do_run_migrations
- run_async_migrations
- run_migrations_online
- call:context.configure
- call:context.begin_transaction
- call:context.run_migrations
- call:async_engine_from_config
## workflows
- change alembic behavior
read: env.py, script.py.mako
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/alembic/versions
## role
Database schema evolution management for the API application, tracking incremental changes to tables supporting users, authentication, projects, git repositories, tool types/instances, config profiles, workspaces, monitoring, and notifications.
Database schema versioning and incremental migration management for the API application's relational database, tracking evolutionary changes to tables, columns, relationships, and data transformations across the project lifecycle.
## parent
index: apps/api/alembic/.pi-map.index.md
map: apps/api/alembic/.pi-map.md
+2 -2
View File
@@ -4,7 +4,7 @@ dir: apps/api/alembic/versions
index: apps/api/alembic/versions/.pi-map.index.md
## role
Database schema evolution management for the API application, tracking incremental changes to tables supporting users, authentication, projects, git repositories, tool types/instances, config profiles, workspaces, monitoring, and notifications.
Database schema versioning and incremental migration management for the API application's relational database, tracking evolutionary changes to tables, columns, relationships, and data transformations across the project lifecycle.
## files
- 0001_initial_schema.py | Defines the initial database schema migration creating five tables (users, ssh_keys, projects, git_repositories, user_configs) with relationships, indexes, and constraints using Alembic. | exp: func:upgrade() → None, call:op.create_table, call:sa.Column, call:sa.String, call:postgresql.UUID, call:sa.DateTime, call:sa.func.now, call:sa.PrimaryKeyConstraint, call:sa.UniqueConstraint, call:op.create_index, call:op.f, call:sa.Text, call:sa.ForeignKeyConstraint, call:sa.Boolean, call:postgresql.JSONB, func:downgrade() → None, call:op.drop_table, call:op.drop_index, call:op.f | dep: alembic, sqlalchemy.dialects, sqlalchemy, postgresql dialect
- 0002_refresh_tokens.py | Alembic database migration that creates a refresh_tokens table with indexes for user authentication token management | exp: func:upgrade() → None, call:op.get_bind, call:sa.inspect, call:inspector.has_table, call:op.create_table, call:sa.Column, call:postgresql.UUID, call:sa.String, call:sa.DateTime, call:sa.ForeignKeyConstraint, call:sa.PrimaryKeyConstraint, call:sa.UniqueConstraint, call:inspector.get_indexes, call:op.f, call:op.create_index, func:downgrade() → None, call:op.get_bind, call:sa.inspect, call:inspector.has_table, call:inspector.get_indexes, call:op.f, call:op.drop_index, call:op.drop_table | dep: alembic, sqlalchemy.dialects, sqlalchemy, sqlalchemy.dialects.postgresql
@@ -51,7 +51,7 @@ Database schema evolution management for the API application, tracking increment
- af8512103d67_add_tool_type_fields.py | Alembic database migration that adds new columns (definition_type, dockerfile_template, build_context, readiness_probe) to the tool_types table with a CHECK constraint on definition_type. | exp: func:upgrade() → None, call:op.add_column, call:sa.Column, call:sa.String, call:sa.Text, call:postgresql.JSONB, call:op.create_check_constraint, call:sa.text, func:downgrade() → None, call:op.drop_constraint, call:op.drop_column | dep: alembic, sqlalchemy.dialects, sqlalchemy, sqlalchemy.dialects.postgresql
- f3d2dc90ba3a_merge_single_interface_and_clone_mode.py | Alembic database migration that merges two prior revisions (single_interface and clone_mode) into a single migration path | exp: func:upgrade() → None, func:downgrade() → None | dep: typing, alembic
## arch
Linear and branched Alembic migration pattern with merge migrations to reconcile divergent branches, using incremental revision files with upgrade/downgrade functions, idempotent operations, and occasional data migrations for schema transformations.
Linear and branched migration history using Alembic (SQLAlchemy's migration tool) with sequential numeric revisions, merge heads to reconcile divergent branches, idempotent data migrations, dialect-specific SQL (PostgreSQL/SQLite), JSON/JSONB columns for flexible schemas, and defensive checks for conditional schema changes; follows additive-only evolution with occasional table drops and column restructures, embedding both schema and data migration logic in revision files.
## tags
column, table, call:op.drop, key, alembic, downgrade, upgrade, constraint
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src
## role
Core application package that bootstraps and configures the Headquarter API FastAPI service with its infrastructure concerns.
Core application package for the Headquarter API, handling configuration, database connectivity, structured logging, and FastAPI application initialization.
## parent
index: apps/api/.pi-map.index.md
map: apps/api/.pi-map.md
+4 -4
View File
@@ -4,15 +4,15 @@ dir: apps/api/src
index: apps/api/src/.pi-map.index.md
## role
Core application package that bootstraps and configures the Headquarter API FastAPI service with its infrastructure concerns.
Core application package for the Headquarter API, handling configuration, database connectivity, structured logging, and FastAPI application initialization.
## files
- __init__.py | Marks the directory as a Python package for the Headquarter API.
- config.py | Defines application configuration settings using Pydantic with environment variable loading, database URL construction, and computed properties for service URLs and OAuth endpoints. | exp: class:Settings, func:build_database_url(user: str, password: str, host: str, port: int, database: str) → str | dep: pydantic, pydantic_settings
- database.py | Configures async SQLAlchemy database engine and session factory, and provides retry logic for database initialization with Alembic migrations via subprocess. | exp: func:init_database(max_retries, retry_delay) → bool, call:range, call:engine.connect, call:test_conn.execute, call:text, call:test_conn.close, call:logger.info, call:asyncio.get_event_loop().run_in_executor, call:subprocess.run, call:logger.debug, call:logger.error, call:asyncio.sleep, call:str(exc).lower, call:logger.warning | dep: asyncio, logging, subprocess, sqlalchemy.ext.asyncio, sqlalchemy.pool, src.config, sqlalchemy
- 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
- database.py | Sets up async SQLAlchemy database engine and session factory, with retry logic for database connectivity testing and Alembic migration execution via subprocess. | exp: func:init_database(max_retries, retry_delay) → bool, call:range, call:engine.connect, call:test_conn.execute, call:text, call:test_conn.close, call:logger.info, call:asyncio.get_event_loop().run_in_executor, call:subprocess.run, call:os.path.dirname, call:os.path.abspath, call:logger.debug, call:logger.error, call:asyncio.sleep, call:str(exc).lower, call:logger.warning | dep: asyncio, logging, os, subprocess, sqlalchemy.ext.asyncio, sqlalchemy.pool, src.config, sqlalchemy
- 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.*
## arch
Layered configuration with Pydantic settings, async SQLAlchemy with Alembic migration integration, structured JSON logging with correlation ID tracking, and FastAPI middleware/routing setup.
Layered architecture with environment-based Pydantic config, async SQLAlchemy with retry patterns, structured JSON logging with correlation IDs, and modular FastAPI setup with middleware and background services.
## tags
src, database, logging, call:logger.info, api, middleware, fastapi, filter
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/api
## role
Defines reusable API validation utilities and package structure for FastAPI router organization.
Defines shared API infrastructure and reusable validation utilities for the API layer.
## parent
index: apps/api/src/.pi-map.index.md
map: apps/api/src/.pi-map.md
+2 -2
View File
@@ -4,12 +4,12 @@ dir: apps/api/src/api
index: apps/api/src/api/.pi-map.index.md
## role
Defines reusable API validation utilities and package structure for FastAPI router organization.
Defines shared API infrastructure and reusable validation utilities for the API layer.
## files
- __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
## arch
Modular utility package with shared Pydantic validators for cross-cutting API schema concerns, following separation of validation logic from route handlers.
Modular package structure with shared Pydantic validators for cross-cutting schema validation concerns.
## tags
validate, raise:value, error, call:isinstance, mount, api, init, path
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/api/config
## role
Exposes REST API endpoints for managing user configuration profiles and settings.
Provides FastAPI API endpoints for managing user configuration settings and configuration profiles.
## parent
index: apps/api/src/api/.pi-map.index.md
map: apps/api/src/api/.pi-map.md
+2 -2
View File
@@ -4,13 +4,13 @@ dir: apps/api/src/api/config
index: apps/api/src/api/config/.pi-map.index.md
## role
Exposes REST API endpoints for managing user configuration profiles and settings.
Provides FastAPI API endpoints for managing user configuration settings and configuration profiles.
## files
- __init__.py | Aggregates and exports configuration-related API routers for the config module. | dep: src.api.config.config_profiles, src.api.config.user_config
- config_profiles.py | FastAPI router providing CRUD endpoints for user config profiles with includes, resolution, defaults, and git URL validation | exp: func:list_config_profiles(project_id, tool_type_id, current_user_id, session), call:select(ConfigProfile) .where(ConfigProfile.user_id == user_uuid) .options, call:selectinload, call:uuid.UUID, call:conditions.append, call:ConfigProfile.project_id.is_, call:ConfigProfile.tool_type_id.is_, call:query.where, call:or_, call:session.execute, call:result.scalars().all, call:profile_to_response, func:create_config_profile(data: ConfigProfileCreate, current_user_id, session), call:create_profile, call:logger.debug, call:profile_to_response, func:get_config_profile(profile_id: str, current_user_id, session), call:get_profile_with_includes, call:uuid.UUID, call:profile_to_response, raise:HTTPException, func:update_config_profile(profile_id: str, data: ConfigProfileUpdate, current_user_id, session), call:get_profile_with_includes, call:uuid.UUID, call:update_profile, call:logger.debug, call:profile_to_response, raise:HTTPException, func:delete_config_profile(profile_id: str, current_user_id, session), call:get_profile_with_includes, call:uuid.UUID, call:session.delete, call:session.commit, call:logger.debug, raise:HTTPException, func:update_profile_includes_endpoint(profile_id: str, data: ConfigProfileIncludeUpdate, current_user_id, session), call:get_profile_with_includes, call:uuid.UUID, call:update_includes, call:session.execute, call:select(ConfigProfileInclude).where, call:inc_result.scalars().all, call:logger.debug, call:profile_to_response, call:list, raise:HTTPException, func:preview_config_profile(profile_id: str, current_user_id, session), call:get_profile_with_includes, call:uuid.UUID, call:resolve_profile, call:resolved_profile_to_dict, raise:HTTPException, func:resolve_default_profile_endpoint(project_id, tool_type_id, current_user_id, session), call:resolve_default_profile, call:uuid.UUID, func:get_default_profiles_endpoint(user_id, session) → dict, call:session.execute, call:select(UserConfig).where, call:result.scalar_one_or_none, func:set_default_profiles_endpoint(data: DefaultProfilesUpdate, user_id, session) → dict, call:validate_default_profiles, call:get_or_create_user_config, call:session.commit, call:session.refresh, func:get_default_profile_for_tool_type_endpoint(tool_type_id: str, user_id, session) → dict, call:session.execute, call:select(UserConfig).where, call:result.scalar_one_or_none, call:user_config.default_profiles.get, func:validate_git_url_endpoint(data: ValidateGitUrlRequest, current_user_id, session) → ValidateGitUrlResponse, call:validate_git_url | dep: logging, uuid, fastapi, sqlalchemy, sqlalchemy.ext.asyncio, sqlalchemy.orm, src.auth.dependencies, src.models, src.schemas.config, src.services.config.config_profile_resolver, src.services.config.crud_service, src.services.config.resolver_service
- user_config.py | Provides FastAPI endpoints to get and update the current user's configuration settings, creating a default config if none exists. | exp: func:_get_or_create_config(session: AsyncSession, user_id: uuid.UUID) → UserConfig, call:session.execute, call:select(UserConfig).where, call:result.scalar_one_or_none, call:UserConfig, call:session.add, call:session.commit, call:session.refresh, func:get_user_config(user_id, session) → UserConfigResponse, call:_get_user, call:_get_or_create_config, call:UserConfigResponse.model_validate, func:update_user_config(data: UserConfigUpdate, user_id, session) → UserConfigResponse, call:_get_user, call:_get_or_create_config, call:data.model_dump, call:logger.debug, call:session.commit, call:session.refresh, call:UserConfigResponse.model_validate | dep: logging, uuid, fastapi, sqlalchemy, sqlalchemy.ext.asyncio, src.auth.dependencies, src.models, src.schemas.user
## arch
FastAPI router modules following domain-driven separation with CRUD patterns, validation logic, and automatic default initialization.
Modular FastAPI router pattern with separate route modules for distinct resource domains (user config vs config profiles), each implementing standard CRUD operations with validation and default initialization logic.
## tags
config, profile, get, user, includes, call:uuid.uuid, or, default
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/api/project
## role
Provides REST API endpoints for project and Git repository management in the backend service.
Provides FastAPI REST API endpoints for project and Git repository management, serving as the HTTP interface layer for the project's core domain operations.
## parent
index: apps/api/src/api/.pi-map.index.md
map: apps/api/src/api/.pi-map.md
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/api/system
## role
Provides system-level API endpoints for monitoring, administration, and infrastructure interaction including dashboards, health checks, events, notifications, and container terminal access.
Provides system-level API endpoints for monitoring, administration, and infrastructure interaction including dashboards, health checks, event streaming, notifications, and container terminal access.
## parent
index: apps/api/src/api/.pi-map.index.md
map: apps/api/src/api/.pi-map.md
+2 -2
View File
@@ -4,7 +4,7 @@ dir: apps/api/src/api/system
index: apps/api/src/api/system/.pi-map.index.md
## role
Provides system-level API endpoints for monitoring, administration, and infrastructure interaction including dashboards, health checks, events, notifications, and container terminal access.
Provides system-level API endpoints for monitoring, administration, and infrastructure interaction including dashboards, health checks, event streaming, notifications, and container terminal access.
## files
- __init__.py | Aggregates and re-exports system API router modules from submodules for centralized access. | dep: src.api.system.dashboard, src.api.system.events, src.api.system.health, src.api.system.instance_proxy, src.api.system.notifications, src.api.system.terminal
- dashboard.py | Provides a FastAPI endpoint that returns a dashboard summary with aggregated counts of projects, repositories, SSH keys, and recent activity for the authenticated user. | exp: func:get_dashboard_summary(user_id, session) → dict, call:session.execute, call:select(func.count()).select_from(Project).where, call:func.count, call:projects_result.scalar, call:select(func.count()).select_from(GitRepository).where, call:repos_result.scalar, call:select(func.count()).select_from(SSHKey).where, call:ssh_keys_result.scalar, call:select(Project) .where(Project.owner_id == user_id) .order_by(Project.created_at.desc()) .limit, call:Project.created_at.desc, call:recent_projects.scalars().all | dep: uuid, fastapi, sqlalchemy, sqlalchemy.ext.asyncio, src.auth.dependencies, src.models, src.models.project, src.models (GitRepository, Project, SSHKey)
@@ -14,7 +14,7 @@ Provides system-level API endpoints for monitoring, administration, and infrastr
- notifications.py | Defines FastAPI REST endpoints for managing user notifications (list, unread count, mark read, dismiss/clear) with support for muted categories from user config. | exp: class:NotificationItem, class:NotificationListResponse, class:UnreadCountResponse, class:MarkAllReadResponse, class:ClearAllResponse, func:_get_mute_categories(session: AsyncSession, user_id: uuid.UUID) → list[str], call:session.execute, call:select(UserConfig).where, call:result.scalar_one_or_none, call:config.config.get, call:isinstance, func:list_notifications(limit, offset, unread_only, user, session) → NotificationListResponse, call:_get_mute_categories, call:notification_service.list_notifications, call:NotificationListResponse, call:NotificationItem.model_validate, func:get_unread_count(user, session) → UnreadCountResponse, call:notification_service.get_unread_count, call:UnreadCountResponse, func:mark_notification_read(notification_id: uuid.UUID, user, session) → NotificationItem, call:notification_service.mark_read, call:NotificationItem.model_validate, raise:HTTPException, func:mark_all_read(user, session) → MarkAllReadResponse, call:notification_service.mark_all_read, call:MarkAllReadResponse, func:clear_all_notifications(user, session) → ClearAllResponse, call:notification_service.dismiss_all, call:ClearAllResponse, func:dismiss_notification(notification_id: uuid.UUID, user, session) → None, call:notification_service.dismiss, raise:HTTPException | dep: uuid, datetime, fastapi, pydantic, sqlalchemy.ext.asyncio, src.auth.dependencies, src.models.user, src.models, src.services.shared.notification_service, sqlalchemy
- terminal.py | Provides WebSocket and HTTP endpoints for managing interactive terminal sessions attached to running Docker container tool instances, including session creation, attachment, input/output streaming, resize/reset control messages, and session listing. | exp: class:SessionRef, method:__init__(self, session, slot_session_id), func:terminal_websocket_default(websocket: WebSocket, instance_id: str, db_session) → None, call:_handle_terminal_websocket, func:terminal_websocket_specific(websocket: WebSocket, instance_id: str, session_id: str, db_session) → None, call:_handle_terminal_websocket, func:_handle_terminal_websocket(websocket: WebSocket, instance_id: str, target_session_id: str | None, db_session: AsyncSession) → None, call:logger.debug, call:websocket.accept, call:uuid.UUID, call:logger.error, call:websocket.close, call:_get_user_from_websocket, call:logger.warning, call:db_session.get, call:get_container_status, call:terminal_manager.get_or_create_session, call:terminal_manager.get_session, call:logger.info, call:terminal_manager.create_session, call:terminal_manager._find_key_by_internal_id, call:terminal_manager.attach_websocket, call:websocket.send_json, call:SessionRef, call:asyncio.create_task, call:_write_loop, call:_heartbeat_loop, call:asyncio.wait, call:len, call:task.cancel, call:str, call:suppress, call:terminal_manager.detach_websocket, func:_write_loop(session_ref: SessionRef, websocket, instance_id: str) → None, call:session.is_alive, call:asyncio.sleep, call:websocket.receive, call:session.write_input, call:text.startswith, call:json.loads, call:ctrl.get, call:logger.debug, call:session.resize, call:session.acknowledge_data, call:websocket.send_json, call:terminal_manager.reset_session, call:terminal_manager.attach_websocket, call:text.encode, func:_heartbeat_loop(websocket: WebSocket) → None, call:asyncio.sleep, call:websocket.send_json, func:_get_terminal_instance(instance_id: uuid.UUID, user_id: uuid.UUID, db_session: AsyncSession) → ToolInstance, call:db_session.get, raise:HTTPException, func:list_terminal_sessions(instance_id: uuid.UUID, user_id, db_session) → dict, call:_get_terminal_instance, call:db_session.execute, call:select(TerminalSessionModel) .where(TerminalSessionModel.instance_id == instance_id) .where(TerminalSessionModel.status != "closed") .order_by, call:TerminalSessionModel.created_at.asc, call:result.scalars().all, call:terminal_manager.get_session, call:str, call:sessions.append, call:live_session.has_websockets, call:row.created_at.isoformat, call:row.last_activity_at.isoformat, func:create_terminal_session(instance_id: uuid.UUID, data: dict, user_id, db_session) → dict, call:_get_terminal_instance, call:db_session.get, call:data.get, call:terminal_manager.create_session, raise:HTTPException, func:close_terminal_session(instance_id: uuid.UUID, session_id: str, user_id, db_session) → dict, call:_get_terminal_instance, call:terminal_manager._find_key_by_internal_id, call:str, call:terminal_manager.get_session, call:terminal_manager.close_session, raise:HTTPException, func:reset_specific_terminal_session(instance_id: uuid.UUID, session_id: str, user_id, db_session) → dict, call:_get_terminal_instance, call:terminal_manager._find_key_by_internal_id, call:str, call:terminal_manager.get_session, call:db_session.get, call:terminal_manager.reset_session, raise:HTTPException, func:rename_terminal_session(instance_id: uuid.UUID, session_id: str, data: dict, user_id, db_session) → dict, call:_get_terminal_instance, call:data.get, call:isinstance, call:terminal_manager.get_session, call:str, call:db_session.get, call:uuid.UUID, call:db_session.commit, raise:HTTPException, func:reset_terminal_session(instance_id: uuid.UUID, user_id, db_session) → dict, call:_get_terminal_instance, call:db_session.get, call:terminal_manager.reset_session, call:logger.info, call:str, call:logger.error, raise:HTTPException, func:_get_user_from_websocket(websocket: WebSocket, db_session: AsyncSession) → uuid.UUID | None, call:websocket.cookies.get, call:Settings, call:decode_session_cookie, call:uuid.UUID, call:str | dep: asyncio, json, logging, uuid, contextlib, fastapi, sqlalchemy, sqlalchemy.ext.asyncio, starlette.websockets, src.auth.dependencies, src.models, src.services.terminal.terminal_manager, src.services.docker, src.auth.session, src.config, starlette
## arch
FastAPI modular router pattern with separate files per domain concern, combining REST endpoints, SSE streaming, WebSocket connections, and HTTP proxying; uses dependency injection for auth and integrates with Docker/container runtime for terminal and instance proxy features.
FastAPI router modules organized by domain concern with async/await patterns, SSE/WebSocket for real-time streaming, proxy pattern for container instance forwarding, and per-user authentication/authorization with connection limiting.
## tags
session, terminal, call:terminal, call:, src, get, response, websocket
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/api/tool
## role
Provides FastAPI REST API endpoints and routers for managing the complete lifecycle of Docker-based tools, including type definitions, instances, sessions, and lifecycle operations.
Provides FastAPI REST API endpoints for managing Docker-based tools, including their definitions, types, instances, lifecycle operations, and active sessions.
## parent
index: apps/api/src/api/.pi-map.index.md
map: apps/api/src/api/.pi-map.md
+4 -4
View File
@@ -4,17 +4,17 @@ dir: apps/api/src/api/tool
index: apps/api/src/api/tool/.pi-map.index.md
## role
Provides FastAPI REST API endpoints and routers for managing the complete lifecycle of Docker-based tools, including type definitions, instances, sessions, and lifecycle operations.
Provides FastAPI REST API endpoints for managing Docker-based tools, including their definitions, types, instances, lifecycle operations, and active sessions.
## files
- __init__.py | Aggregates and exports all tool-related API routers from submodules as a unified module interface. | dep: src.api.tool.sessions, src.api.tool.tool_definitions, src.api.tool.tool_instances, src.api.tool.tool_lifecycle, src.api.tool.tool_types
- sessions.py | API endpoint that retrieves all active tool instances (sessions) for the currently authenticated user with related metadata | exp: func:get_user_sessions(user_id, session) → dict, call:_get_user, call:session.execute, call:select(ToolInstance) .where(ToolInstance.owner_id == user_id) .where( ToolInstance.status.in_( ["running", "building", "pending", "stopped", "error"] ) ) .order_by, call:ToolInstance.status.in_, call:ToolInstance.created_at.desc, call:result.scalars().all, call:session.get, call:sessions.append, call:str, call:instance.created_at.isoformat | dep: uuid, fastapi, sqlalchemy, sqlalchemy.ext.asyncio, src.auth.dependencies, src.models
- sessions.py | Provides a FastAPI endpoint to retrieve all active tool instances (sessions) for the currently authenticated user with related metadata. | exp: func:get_user_sessions(user_id, session) → dict, call:_get_user, call:session.execute, call:select(ToolInstance) .where(ToolInstance.owner_id == user_id) .where( ToolInstance.status.in_( ["running", "building", "pending", "stopped", "error"] ) ) .order_by, call:ToolInstance.status.in_, call:ToolInstance.created_at.desc, call:result.scalars().all, call:session.get, call:sessions.append, call:str, call:instance.created_at.isoformat | dep: uuid, fastapi, sqlalchemy, sqlalchemy.ext.asyncio, src.auth.dependencies, src.models, src.models (GitRepository, Project, ToolInstance, ToolType, Workspace)
- tool_definitions.py | FastAPI router providing CRUD endpoints and manifest compilation for tool definition manifests stored in a database. | exp: class:CreateToolDefinitionRequest, class:UpdateToolDefinitionRequest, func:create_tool_definition(data: CreateToolDefinitionRequest, user_id, session) → dict, call:uuid.UUID, call:session.get, call:session.execute, call:select(ToolDefinitionManifest).where, call:existing.scalar_one_or_none, call:ToolDefinitionManifest, call:session.add, call:session.commit, call:session.refresh, call:logger.info, call:str, call:definition.created_at.isoformat, raise:HTTPException, func:list_tool_definitions(user_id, session, include_bases) → dict, call:select, call:query.where, call:ToolDefinitionManifest.is_base.is_, call:session.execute, call:query.order_by, call:ToolDefinitionManifest.created_at.desc, call:result.scalars().all, call:str, call:d.created_at.isoformat, func:get_tool_definition(definition_id: uuid.UUID, user_id, session) → dict, call:session.get, call:str, call:definition.created_at.isoformat, call:definition.updated_at.isoformat, raise:HTTPException, func:update_tool_definition(definition_id: uuid.UUID, data: UpdateToolDefinitionRequest, user_id, session) → dict, call:session.get, call:session.commit, call:session.refresh, call:logger.info, call:str, call:definition.updated_at.isoformat, raise:HTTPException, func:delete_tool_definition(definition_id: uuid.UUID, user_id, session) → dict, call:session.get, call:session.execute, call:select(ToolType).where, call:result.scalars().all, call:", ".join, call:session.delete, call:session.commit, call:logger.info, call:str, raise:HTTPException, func:compile_tool_definition(definition_id: uuid.UUID, user_id, session) → dict, call:session.get, call:dict, call:resolve_base, call:deep_merge, call:compile_dockerfile, call:compile_entrypoint, call:compute_image_tag, call:compile_compose, call:session.commit, call:str, raise:HTTPException | dep: logging, uuid, fastapi, pydantic, sqlalchemy, sqlalchemy.ext.asyncio, src.auth.dependencies, src.models, src.services.build.manifest_compiler
- tool_instances.py | Provides FastAPI REST endpoints for managing tool instances including CRUD operations, logs, health checks, tunnel recreation, event history, and HTTP proxying to running containers. | exp: func:create_instance(project_id: uuid.UUID, repo_id: uuid.UUID, data: CreateInstanceRequest, user_id, session) → dict, call:_get_user, call:_get_owned_project, call:create_tool_instance, call:str, call:instance.created_at.isoformat, raise:HTTPException, func:list_instances(project_id: uuid.UUID, repo_id: uuid.UUID, user_id, session) → list[dict], call:_get_user, call:_get_owned_project, call:session.execute, call:select(ToolInstance) .where(ToolInstance.repository_id == repo_id) .where(ToolInstance.owner_id == user_id) .order_by, call:ToolInstance.created_at.desc, call:result.scalars().all, call:str, call:i.created_at.isoformat, func:get_instance(project_id: uuid.UUID, repo_id: uuid.UUID, instance_id: uuid.UUID, user_id, session) → dict, call:_get_user, call:_get_owned_project, call:session.get, call:get_container_status, call:str, call:instance.created_at.isoformat, call:instance.last_started_at.isoformat, raise:HTTPException, func:rename_instance(project_id: uuid.UUID, repo_id: uuid.UUID, instance_id: uuid.UUID, data: dict, user_id, session) → dict, call:_get_user, call:_get_owned_project, call:data.get("display_name", "").strip, call:rename_tool_instance, call:str, raise:HTTPException, func:get_instance_logs(project_id: uuid.UUID, repo_id: uuid.UUID, instance_id: uuid.UUID, tail, user_id, session) → dict, call:_get_user, call:_get_owned_project, call:session.get, call:get_container_logs, raise:HTTPException, func:recreate_tunnel_endpoint(project_id: uuid.UUID, repo_id: uuid.UUID, instance_id: uuid.UUID, user_id, session) → dict, call:_get_user, call:_get_owned_project, call:recreate_instance_tunnel, raise:HTTPException, func:check_instance_tunnel_health(project_id: uuid.UUID, repo_id: uuid.UUID, instance_id: uuid.UUID, user_id, session) → dict, call:_get_user, call:_get_owned_project, call:session.get, call:get_container_status, call:instance.probe_result.get, call:"\n".join, call:check_tunnel_health, call:tunnel_health.get, raise:HTTPException, func:get_instance_events(project_id: uuid.UUID, repo_id: uuid.UUID, instance_id: uuid.UUID, limit, user_id, session) → list[dict], call:_get_user, call:_get_owned_project, call:session.get, call:session.execute, call:select(InstanceEvent) .where(InstanceEvent.instance_id == instance_id) .order_by(InstanceEvent.created_at.desc()) .limit, call:InstanceEvent.created_at.desc, call:result.scalars().all, call:str, call:row.created_at.isoformat, raise:HTTPException, func:proxy_to_instance(request: Request, project_id: uuid.UUID, repo_id: uuid.UUID, instance_id: uuid.UUID, path, user_id, session) → Response, call:session.get, call:str, call:dict, call:headers.pop, call:httpx.AsyncClient, call:request.body, call:client.request, call:logger.error, call:response_headers.pop, call:Response, raise:HTTPException | dep: logging, uuid, httpx, fastapi, sqlalchemy, sqlalchemy.ext.asyncio, src.auth.dependencies, src.models, src.services.docker, src.services.shared.tunnel, src.schemas.tool, src.services.tool.instance_service
- tool_lifecycle.py | FastAPI router providing REST endpoints for managing Docker-based tool instance lifecycle operations (start, stop, restart, delete). | exp: func:start_instance(project_id: uuid.UUID, repo_id: uuid.UUID, instance_id: uuid.UUID, data, user_id, session) → dict, call:_get_user, call:_get_owned_project, call:start_tool_instance, raise:HTTPException, func:stop_instance(project_id: uuid.UUID, repo_id: uuid.UUID, instance_id: uuid.UUID, user_id, session) → dict, call:_get_user, call:_get_owned_project, call:stop_tool_instance, raise:HTTPException, func:restart_instance(project_id: uuid.UUID, repo_id: uuid.UUID, instance_id: uuid.UUID, user_id, session) → dict, call:_get_user, call:_get_owned_project, call:restart_tool_instance, raise:HTTPException, func:delete_instance(project_id: uuid.UUID, repo_id: uuid.UUID, instance_id: uuid.UUID, force, user_id, session) → None, call:_get_user, call:_get_owned_project, call:delete_tool_instance, call:str, call:detail.lower, raise:HTTPException | dep: logging, uuid, fastapi, sqlalchemy.ext.asyncio, src.auth.dependencies, src.schemas.tool, src.services.tool.instance_service
- tool_types.py | Defines FastAPI routes for CRUD operations and validation of Docker tool types with compose/dockerfile/manifest definitions. | exp: func:_require_admin(user: User) → None, func:create_tool_type(data: ToolTypeCreate, user_id, session) → ToolType, call:_get_user, call:_require_admin, call:session.scalar, call:select(ToolType).where, call:ToolType, call:session.add, call:session.commit, call:session.refresh, raise:HTTPException, func:list_tool_types(user_id, session) → list[ToolType], call:_get_user, call:session.execute, call:select(ToolType).order_by, call:list, call:result.scalars().all, func:get_tool_type(tool_type_id: uuid.UUID, user_id, session) → ToolType, call:_get_user, call:session.get, raise:HTTPException, func:update_tool_type(tool_type_id: uuid.UUID, data: ToolTypeUpdate, user_id, session) → ToolType, call:_get_user, call:_require_admin, call:session.get, call:data.model_dump, call:update_data.get, call:validate_compose_yaml, call:check_port_exposed, call:validate_required_variables, call:update_data.items, call:setattr, call:session.commit, call:session.refresh, raise:HTTPException, func:validate_tool_type_template(data: ToolTypeValidateRequest, user_id, session) → dict, call:_get_user, call:errors.append, call:validate_compose_yaml, call:str, call:data.dockerfile_template.strip().startswith, call:len, func:validate_tool_type(tool_type_id: uuid.UUID, user_id, session) → dict, call:_get_user, call:session.get, call:errors.append, call:validate_compose_yaml, call:str, call:tool_type.dockerfile_template.strip().startswith, call:len, raise:HTTPException, func:delete_tool_type(tool_type_id: uuid.UUID, user_id, session) → None, call:_get_user, call:_require_admin, call:session.get, call:session.delete, call:session.commit, raise:HTTPException | dep: uuid, fastapi, sqlalchemy, sqlalchemy.ext.asyncio, src.api.tool.tool_types_validation, src.auth.dependencies, src.models, src.models.user, src.schemas.tool
- tool_types_validation.py | Validates Docker Compose YAML templates by sanitizing template variables, parsing YAML, checking required structure, verifying port exposure, and ensuring required variables are present. | exp: func:sanitize_template_vars(template: str) → str, call:re.sub, func:validate_compose_yaml(template: str) → dict, call:sanitize_template_vars, call:yaml.safe_load, call:isinstance, raise:ValueError, func:check_port_exposed(parsed: dict, port: int) → bool, call:str, call:isinstance, call:parsed["services"].values, func:validate_required_variables(template: str, variables: list[str]) → None, raise:HTTPException | dep: re, yaml, fastapi, fastapi.HTTPException, fastapi.status
- tool_types_validation.py | Validates Docker Compose YAML templates by sanitizing template variables, parsing YAML structure, checking port exposure, and verifying required variables exist. | exp: func:sanitize_template_vars(template: str) → str, call:re.sub, func:validate_compose_yaml(template: str) → dict, call:sanitize_template_vars, call:yaml.safe_load, call:isinstance, raise:ValueError, func:check_port_exposed(parsed: dict, port: int) → bool, call:str, call:isinstance, call:parsed["services"].values, call:port_mapping.split, call:mapping.split, func:validate_required_variables(template: str, variables: list[str]) → None, raise:HTTPException | dep: re, yaml, fastapi
## arch
Modular FastAPI router composition pattern with separated concerns across CRUD operations, validation, lifecycle management, and proxying, aggregated through `__init__.py` for unified module interface.
Modular FastAPI router organization with clear separation of concerns across CRUD operations, Docker lifecycle management, YAML/Compose validation, and container proxying/tunneling.
## tags
get, call:, tool, raise:httpexception, user, instance, call:str, call:session.get
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/api/user
## role
Provides user-facing API endpoints for authentication, profile management, and SSH key operations in a FastAPI backend application.
Provides authentication, user profile management, and SSH key operations for the API backend.
## parent
index: apps/api/src/api/.pi-map.index.md
map: apps/api/src/api/.pi-map.md
+2 -2
View File
@@ -4,14 +4,14 @@ dir: apps/api/src/api/user
index: apps/api/src/api/user/.pi-map.index.md
## role
Provides user-facing API endpoints for authentication, profile management, and SSH key operations in a FastAPI backend application.
Provides authentication, user profile management, and SSH key operations for the API backend.
## files
- __init__.py | Aggregates and exports user-related API routers from submodules for easy importing | dep: src.api.user.auth, src.api.user.ssh_keys, src.api.user.users
- auth.py | Implements OAuth2/OIDC authentication endpoints for a FastAPI application using Authentik as the identity provider, including login initiation, callback handling, logout, and current user retrieval. | exp: func:get_db_session() → AsyncGenerator[AsyncSession, None], call:SessionLocal, func:login(next) → RedirectResponse, call:Settings, call:token_urlsafe, call:build_login_redirect_url, call:logger.debug, call:RedirectResponse, call:response.set_cookie, func:callback(code: str, state: str, auth_state, auth_next, session) → RedirectResponse, call:logger.debug, call:logger.warning, call:Settings, call:httpx.AsyncClient, call:exchange_code_for_tokens, call:logger.info, call:logger.error, call:fetch_user_info, call:str, call:user_info.get, call:session.scalar, call:select(User).where, call:User, call:session.add, call:session.commit, call:session.refresh, call:create_session_cookie, call:build_cookie_options, call:cast, call:bool, call:cookie_options.get, call:RedirectResponse, call:redirect_response.set_cookie, call:redirect_response.delete_cookie, raise:HTTPException, func:logout(response: Response) → dict[str, str], call:Settings, call:build_cookie_options, call:cast, call:bool, call:str, call:cookie_options.get, call:response.delete_cookie, func:me(session_cookie, session) → dict[str, Any], call:logger.debug, call:bool, call:logger.warning, call:Settings, call:decode_session_cookie, call:session.get, call:logger.info, call:str, raise:HTTPException | dep: logging, secrets, typing, httpx, fastapi, fastapi.responses, sqlalchemy, sqlalchemy.ext.asyncio, src.auth.cookies, src.auth.oidc, src.auth.session, src.config, src.database, src.models.user
- ssh_keys.py | Implements a FastAPI router for managing Ed25519 SSH key pairs, including generation, storage with encrypted private keys, listing, deletion, and cryptographic signing/verification operations. | exp: func:_get_fernet() → Fernet, call:Settings, call:hashlib.sha256(settings.session_secret.encode()).digest, call:settings.session_secret.encode, call:base64.urlsafe_b64encode, call:Fernet, func:generate_ssh_key_pair() → tuple[str, str], call:Ed25519PrivateKey.generate, call:private_key.public_key, call:private_key.private_bytes, call:serialization.NoEncryption, call:public_key.public_bytes, call:private_bytes.decode, call:public_bytes.decode, func:create_ssh_key(data: SSHKeyCreate, user_id, session) → SSHKey, call:_get_user, call:generate_ssh_key_pair, call:_get_fernet, call:fernet.encrypt(private_key.encode()).decode, call:private_key.encode, call:SSHKey, call:session.add, call:session.commit, call:session.refresh, func:list_ssh_keys(user_id, session) → list[SSHKey], call:_get_user, call:session.execute, call:select(SSHKey).where, call:list, call:result.scalars().all, func:delete_ssh_key(key_id: uuid.UUID, user_id, session) → None, call:_get_user, call:session.get, call:session.delete, call:session.commit, raise:HTTPException, func:sign_payload(key_id: uuid.UUID, data: SignPayloadRequest, user_id, session) → SignatureResponse, call:_get_user, call:session.get, call:_get_fernet, call:fernet.decrypt(ssh_key.private_key_encrypted.encode()).decode, call:ssh_key.private_key_encrypted.encode, call:serialization.load_ssh_private_key, call:private_key_pem.encode, call:private_key.sign, call:data.payload.encode, call:SignatureResponse, call:base64.b64encode(signature).decode, raise:HTTPException, func:verify_signature(key_id: uuid.UUID, data: VerifySignatureRequest, user_id, session) → VerifySignatureResponse, call:_get_user, call:session.get, call:serialization.load_ssh_public_key, call:ssh_key.public_key.encode, call:base64.b64decode, call:public_key.verify, call:data.payload.encode, call:VerifySignatureResponse, raise:HTTPException | dep: base64, uuid, cryptography.fernet, cryptography.hazmat.primitives, cryptography.hazmat.primitives.asymmetric.ed25519, fastapi, sqlalchemy, sqlalchemy.ext.asyncio, src.auth.dependencies, src.config, src.models, src.schemas.project, hashlib, cryptography
- users.py | Implements FastAPI endpoints for authenticated user profile management including retrieval, updates, and avatar uploads. | exp: func:get_profile(user_id, session) → User, call:_get_user, func:update_profile(data: UserProfileUpdate, user_id, session) → User, call:_get_user, call:len, call:data.name.strip, call:data.email.strip, call:session.commit, call:session.refresh, raise:HTTPException, func:upload_avatar(file: UploadFile, user_id, session) → User, call:_get_user, call:file.read, call:len, call:Path, call:old_path.exists, call:old_path.unlink, call:filename_part.split(".")[-1].lower, call:uuid.uuid4, call:file_path.write_bytes, call:session.commit, call:session.refresh, raise:HTTPException | dep: uuid, pathlib, fastapi, sqlalchemy.ext.asyncio, src.auth.dependencies, src.models.user, src.schemas.user
## arch
Modular FastAPI router pattern with separate submodule files per domain concern (auth, SSH keys, users), aggregated via __init__.py, using OAuth2/OIDC external identity provider (Authentik) and encrypted key storage for cryptographic operations.
Modular FastAPI router pattern with OAuth2/OIDC external identity provider integration, encrypted key storage, and file-based avatar handling.
## tags
user, get, call:, key, ssh, src, cookie, raise:httpexception
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/api/workspace
## role
Provides FastAPI REST endpoints for workspace management, file operations, and git integration in user-scoped development environments.
Provides FastAPI REST API endpoints for workspace management, including CRUD operations, file access, git version control, and tool instance management within user-scoped workspaces.
## parent
index: apps/api/src/api/.pi-map.index.md
map: apps/api/src/api/.pi-map.md
+3 -3
View File
@@ -4,15 +4,15 @@ dir: apps/api/src/api/workspace
index: apps/api/src/api/workspace/.pi-map.index.md
## role
Provides FastAPI REST endpoints for workspace management, file operations, and git integration in user-scoped development environments.
Provides FastAPI REST API endpoints for workspace management, including CRUD operations, file access, git version control, and tool instance management within user-scoped workspaces.
## 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
- 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_instances.py | Defines API endpoints for listing tool instances associated with a specific workspace, verifying workspace ownership. | 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_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
- 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
## arch
Modular router composition with domain-separated endpoint modules (files, git, instances, workspaces) using FastAPI dependency injection for workspace ownership verification and nested resource URL patterns.
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.
## tags
workspace, get, raise:httpexception, call:, at.isoformat, git, call:select, call:data.get
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/auth
## role
Provides authentication and authorization infrastructure for the API, including OIDC/OAuth2 integration, session management, and FastAPI dependency injection.
Provides authentication and authorization infrastructure for the API using OIDC/OAuth2 with Authentik, session cookies, and FastAPI dependencies.
## parent
index: apps/api/src/.pi-map.index.md
map: apps/api/src/.pi-map.md
+2 -2
View File
@@ -4,7 +4,7 @@ dir: apps/api/src/auth
index: apps/api/src/auth/.pi-map.index.md
## role
Provides authentication and authorization infrastructure for the API, including OIDC/OAuth2 integration, session management, and FastAPI dependency injection.
Provides authentication and authorization infrastructure for the API using OIDC/OAuth2 with Authentik, session cookies, and FastAPI dependencies.
## files
- __init__.py | Re-exports authentication utility functions from submodules to provide a unified public API for the auth package | dep: src.auth.cookies, src.auth.oidc, src.auth.session
- cookies.py | Builds a dictionary of HTTP cookie options from application settings for secure cookie configuration. | exp: func:build_cookie_options(settings: Settings) → dict[str, str | bool | None] | dep: src.config, src.config.Settings
@@ -12,7 +12,7 @@ Provides authentication and authorization infrastructure for the API, including
- oidc.py | Implements OIDC/OAuth2 authentication flow with Authentik, including login URL construction, authorization code exchange for tokens, and user info retrieval. | exp: func:build_login_redirect_url(settings: Settings, redirect_uri: str, state: str) → str, call:urlencode, func:exchange_code_for_tokens(settings: Settings, code: str, redirect_uri: str, client: httpx.AsyncClient) → dict[str, str], call:client.post, call:response.raise_for_status, call:response.json, call:payload.get, func:fetch_user_info(settings: Settings, access_token: str, client: httpx.AsyncClient) → dict[str, Any], call:client.get, call:response.raise_for_status, call:response.json | dep: typing, urllib.parse, httpx, src.config
- session.py | Implements creation and verification of signed session cookies using HMAC-SHA256 in a JWS-like format. | exp: func:_base64url_encode(data: bytes) → str, call:base64.urlsafe_b64encode(data).rstrip(b"=").decode, func:_base64url_decode(data: str) → bytes, call:len, call:base64.urlsafe_b64decode, func:create_session_cookie(settings: Settings, user_id: str) → str, call:int, call:(datetime.now(timezone.utc) + timedelta(hours=settings.session_ttl_hours)).timestamp, call:datetime.now, call:timedelta, call:_base64url_encode, call:json.dumps({"alg": "HS256", "typ": "session"}).encode, call:json.dumps(payload).encode, call:hmac.new( settings.session_secret.encode(), message.encode(), hashlib.sha256, ).digest, call:settings.session_secret.encode, call:message.encode, func:decode_session_cookie(settings: Settings, cookie_value: str) → dict[str, Any], call:cookie_value.split, call:len, call:hmac.new( settings.session_secret.encode(), message.encode(), hashlib.sha256, ).digest, call:settings.session_secret.encode, call:message.encode, call:_base64url_encode, call:hmac.compare_digest, call:_base64url_decode, call:json.loads, call:payload.get, call:int, call:datetime.now(timezone.utc).timestamp, raise:ValueError | dep: hmac, hashlib, json, base64, datetime, typing, src.config, src.config.Settings
## arch
Modular utility package with separation of concerns across cookies, sessions, OIDC flows, and FastAPI dependencies; uses HMAC-SHA256 JWS-like tokens and external Authentik identity provider.
Modular security layer with separation of concerns: protocol handling (OIDC), transport security (cookies/sessions), framework integration (dependencies), and clean public API (re-exports).
## tags
session, src, cookie, user, get, base64url, raise:httpexception, call:
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/models
## role
Provides the core database model layer with a centralized public API, defining SQLAlchemy base classes and reusable mixins for consistent schema patterns across the API application.
Centralized database model definitions and shared infrastructure for the API's data layer.
## parent
index: apps/api/src/.pi-map.index.md
map: apps/api/src/.pi-map.md
+2 -2
View File
@@ -4,12 +4,12 @@ dir: apps/api/src/models
index: apps/api/src/models/.pi-map.index.md
## role
Provides the core database model layer with a centralized public API, defining SQLAlchemy base classes and reusable mixins for consistent schema patterns across the API application.
Centralized database model definitions and shared infrastructure for the API's data layer.
## files
- __init__.py | Re-exports model classes from submodules to provide a centralized public API for the src.models package | dep: src.models.base, src.models.config.config_profile, src.models.project.git_repository, src.models.project.project, src.models.project.workspace, src.models.system.health_check, src.models.system.instance_event, src.models.system.notification, src.models.system.terminal_session, src.models.tool.tool_definition_manifest, src.models.tool.tool_instance, src.models.tool.tool_type, src.models.user.ssh_key, src.models.user.user, src.models.user.user_config
- base.py | Defines SQLAlchemy base model and reusable mixins for UUID primary keys and automatic timestamp tracking in database models. | exp: class:Base, class:UUIDPrimaryKeyMixin, class:TimestampMixin | dep: uuid, datetime, sqlalchemy, sqlalchemy.orm
## arch
Uses the declarative base pattern with mixin composition for cross-cutting concerns (UUIDs, timestamps), and a facade/aggregate module pattern via __init__.py re-exports to simplify imports for consumers.
SQLAlchemy ORM with declarative base, mixin-based composition for cross-cutting concerns (UUIDs, timestamps), and explicit package-level re-exports for clean public API surface.
## tags
models, src, base, project, system, user, mixin, tool
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/models/config
## role
Provides SQLAlchemy ORM models for managing configuration profiles and their hierarchical includes in the API application.
Provides SQLAlchemy ORM models for configuration profiles that manage environment variables, mounts, files, and git mounts with support for profile inheritance and user/project/tool associations.
## parent
index: apps/api/src/models/.pi-map.index.md
map: apps/api/src/models/.pi-map.md
+2 -2
View File
@@ -4,12 +4,12 @@ dir: apps/api/src/models/config
index: apps/api/src/models/config/.pi-map.index.md
## role
Provides SQLAlchemy ORM models for managing configuration profiles and their hierarchical includes in the API application.
Provides SQLAlchemy ORM models for configuration profiles that manage environment variables, mounts, files, and git mounts with support for profile inheritance and user/project/tool associations.
## files
- __init__.py | Exports config model classes from a subpackage for simplified importing | dep: src.models.config.config_profile
- config_profile.py | Defines SQLAlchemy ORM models for configuration profiles and their includes, storing environment variables, runtime hints, mounts, files, and git mounts with user/project/tool associations and self-referential inclusion relationships. | exp: class:ConfigProfile, class:ConfigProfileInclude | dep: uuid, typing, sqlalchemy, sqlalchemy.orm, src.models.base, src.models.project, src.models, src.models.user, src.models (ToolType)
## arch
Uses SQLAlchemy declarative ORM pattern with self-referential many-to-many relationships for profile inclusion, and associations to users, projects, and tools.
Uses SQLAlchemy ORM with declarative base pattern, implementing self-referential many-to-many relationships for profile inclusion, association tables for user/project/tool ownership, and polymorphic-like configuration through profile inheritance rather than class inheritance.
## tags
config, src, models, profile, sqlalchemy, init, orm, mounts
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/models/project
## role
Defines the core data models for project-related entities (GitRepository, Project, Workspace) using SQLAlchemy ORM.
Defines the core domain data models for project management, representing Git repositories, projects, and workspaces as SQLAlchemy ORM entities with their relationships.
## parent
index: apps/api/src/models/.pi-map.index.md
map: apps/api/src/models/.pi-map.md
+2 -2
View File
@@ -4,14 +4,14 @@ dir: apps/api/src/models/project
index: apps/api/src/models/project/.pi-map.index.md
## role
Defines the core data models for project-related entities (GitRepository, Project, Workspace) using SQLAlchemy ORM.
Defines the core domain data models for project management, representing Git repositories, projects, and workspaces as SQLAlchemy ORM entities with their relationships.
## files
- __init__.py | Exports the three main project model classes (GitRepository, Project, Workspace) as the public API for the models.project package. | dep: src.models.project.git_repository, src.models.project.project, src.models.project.workspace
- git_repository.py | Defines a SQLAlchemy ORM model for Git repositories with relationships to projects, users, and SSH keys. | exp: class:GitRepository | dep: uuid, datetime, typing, sqlalchemy, sqlalchemy.orm, src.models.base, src.models.project, src.models, src.models.user, src.models.ssh_key
- project.py | Defines a SQLAlchemy ORM model for a Project entity with relationships to users, Git repositories, and SSH keys. | exp: class:Project | dep: uuid, typing, sqlalchemy, sqlalchemy.orm, src.models.base, src.models, src.models.user, src.models.GitRepository, src.models.SSHKey, src.models.user.User
- workspace.py | Defines a SQLAlchemy ORM model for persistent writable Git repository clones associated with users. | exp: class:Workspace | dep: uuid, datetime, typing, sqlalchemy, sqlalchemy.orm, src.models.base, src.models, src.models.user, src.models.GitRepository, src.models.user.User
## arch
Standard SQLAlchemy ORM pattern with declarative models, package-level public API abstraction via __init__.py, and bidirectional relationships between entities.
Standard SQLAlchemy ORM model layer with declarative base pattern, using __init__.py as a public API facade to expose the three main entity classes while keeping implementation details in separate modules.
## tags
models, src, project, sqlalchemy, git, user, workspace, orm
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/models/system
## role
Provides SQLAlchemy ORM models for system-level operational and audit data including health checks, instance events, notifications, and terminal sessions.
Provides database persistence models for system-level operational concerns including health monitoring, audit logging, user notifications, and terminal session management.
## parent
index: apps/api/src/models/.pi-map.index.md
map: apps/api/src/models/.pi-map.md
+2 -2
View File
@@ -4,7 +4,7 @@ dir: apps/api/src/models/system
index: apps/api/src/models/system/.pi-map.index.md
## role
Provides SQLAlchemy ORM models for system-level operational and audit data including health checks, instance events, notifications, and terminal sessions.
Provides database persistence models for system-level operational concerns including health monitoring, audit logging, user notifications, and terminal session management.
## files
- __init__.py | Exports system-related model classes from a package for convenient importing. | dep: src.models.system.health_check, src.models.system.instance_event, src.models.system.notification, src.models.system.terminal_session
- health_check.py | Defines a SQLAlchemy ORM model for storing health check snapshots of tool instances with various status and probe fields. | exp: class:HealthCheck | dep: uuid, datetime, sqlalchemy, sqlalchemy.orm, src.models.base
@@ -12,7 +12,7 @@ Provides SQLAlchemy ORM models for system-level operational and audit data inclu
- notification.py | Defines a SQLAlchemy ORM model for storing user notifications with metadata, read/dismissed tracking, and polymorphic source references. | exp: class:Notification | dep: datetime, typing, uuid, sqlalchemy, sqlalchemy.orm, sqlalchemy.sql, src.models.base
- terminal_session.py | Defines a SQLAlchemy database model for storing terminal session metadata with lifecycle tracking. | exp: class:TerminalSessionModel | dep: uuid, datetime, sqlalchemy, sqlalchemy.orm, src.models.base
## arch
Standard SQLAlchemy declarative ORM pattern with timestamped base models, polymorphic relationships (notification sources), lifecycle state tracking, and audit fields (user attribution, status enums).
Uses SQLAlchemy ORM declarative models with consistent patterns including timestamp tracking, JSON metadata columns, enum-based status fields, and polymorphic relationships for extensible source attribution.
## tags
sqlalchemy, src, models, model, orm, system, notification, health
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/models/tool
## role
Defines SQLAlchemy ORM models for managing tool definitions, instances, and types in a container-based deployment system.
Database models for containerized tool lifecycle management, covering tool definitions, deployment instances, and categorization types.
## parent
index: apps/api/src/models/.pi-map.index.md
map: apps/api/src/models/.pi-map.md
+3 -3
View File
@@ -4,14 +4,14 @@ dir: apps/api/src/models/tool
index: apps/api/src/models/tool/.pi-map.index.md
## role
Defines SQLAlchemy ORM models for managing tool definitions, instances, and types in a container-based deployment system.
Database models for containerized tool lifecycle management, covering tool definitions, deployment instances, and categorization types.
## files
- __init__.py | Exports the public API for the tool models module by re-exporting three key classes. | dep: src.models.tool.tool_definition_manifest, src.models.tool.tool_instance, src.models.tool.tool_type
- tool_definition_manifest.py | Defines a SQLAlchemy ORM model for storing tool definition manifests that compile to Dockerfiles and Compose files, supporting both base definitions and tool-specific definitions with inheritance. | exp: class:ToolDefinitionManifest | dep: uuid, typing, sqlalchemy, sqlalchemy.orm, src.models.base, src.models.user
- tool_instance.py | Defines a SQLAlchemy ORM model for tool instances that represent deployed tools with container/runtime metadata and relationships to users, projects, repositories, and workspaces. | exp: class:ToolInstance | dep: uuid, datetime, typing, sqlalchemy, sqlalchemy.orm, src.models.base, src.models, src.models.project, src.models.user, src.models (ConfigProfile, GitRepository, Project, ToolType, User, Workspace)
- tool_instance.py | Defines a SQLAlchemy ORM model for tool instances that represent deployed tools with container metadata, status tracking, and relationships to users, projects, workspaces, and other entities. | exp: class:ToolInstance | dep: uuid, datetime, typing, sqlalchemy, sqlalchemy.orm, src.models.base, src.models, src.models.project, src.models.user, src.models (ConfigProfile, GitRepository, Project, ToolType, User, Workspace)
- tool_type.py | Defines a SQLAlchemy ORM model for tool types that represent configurable categories of tools with deployment templates, manifest references, and metadata. | exp: class:ToolType | dep: uuid, typing, sqlalchemy, sqlalchemy.orm, src.models.base, src.models.tool.tool_definition_manifest, src.models.user
## arch
Domain-driven SQLAlchemy ORM models with inheritance patterns (base/tool-specific manifests), rich relationships (users, projects, repositories, workspaces), and template-based deployment abstractions.
SQLAlchemy ORM with declarative models using inheritance hierarchies, relationship mappings, and polymorphic manifest compilation for Docker/Compose deployment.
## tags
tool, models, src, sqlalchemy, orm, definition, manifest, base
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/models/user
## role
Provides the core data models for user identity, authentication credentials, and personal configuration in the API's database layer.
Provides SQLAlchemy ORM data models for user authentication, SSH key storage, and per-user configuration management.
## parent
index: apps/api/src/models/.pi-map.index.md
map: apps/api/src/models/.pi-map.md
+2 -2
View File
@@ -4,14 +4,14 @@ dir: apps/api/src/models/user
index: apps/api/src/models/user/.pi-map.index.md
## role
Provides the core data models for user identity, authentication credentials, and personal configuration in the API's database layer.
Provides SQLAlchemy ORM data models for user authentication, SSH key storage, and per-user configuration management.
## files
- __init__.py | Exports the user-related model classes (SSHKey, User, UserConfig) from a package for convenient importing. | dep: src.models.user.ssh_key, src.models.user.user, src.models.user.user_config
- ssh_key.py | Defines an SSHKey SQLAlchemy ORM model for storing encrypted SSH key pairs with user and optional project associations. | exp: class:SSHKey | dep: uuid, typing, sqlalchemy, sqlalchemy.orm, src.models.base, src.models.project, src.models.user
- user.py | Defines a SQLAlchemy ORM model for a User entity with authentication fields and relationships to projects, SSH keys, and user configuration. | exp: class:User | dep: typing, sqlalchemy, sqlalchemy.orm, src.models.base, src.models.project, src.models, src.models.SSHKey, src.models.UserConfig
- user_config.py | Defines a SQLAlchemy model for storing per-user JSON configuration with typed property accessors for default profile IDs. | exp: class:UserConfig | dep: uuid, typing, sqlalchemy, sqlalchemy.orm, src.models.base, src.models.user
## arch
Follows SQLAlchemy ORM declarative model pattern with package-level aggregation via __init__.py, using explicit table relationships (foreign keys, one-to-many associations) and a JSON-backed configuration store with typed property accessors.
Classic SQLAlchemy ORM model package pattern with declarative models, explicit table relationships, and a package-level __init__.py facade for clean imports.
## tags
user, src, models, sqlalchemy, sshkey, orm, model, ssh
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/schemas
## role
Defines Pydantic schemas for data validation, serialization, and API request/response models in the FastAPI application.
Defines Pydantic schemas for data validation and serialization in the API layer.
## parent
index: apps/api/src/.pi-map.index.md
map: apps/api/src/.pi-map.md
+2 -2
View File
@@ -4,11 +4,11 @@ dir: apps/api/src/schemas
index: apps/api/src/schemas/.pi-map.index.md
## role
Defines Pydantic schemas for data validation, serialization, and API request/response models in the FastAPI application.
Defines Pydantic schemas for data validation and serialization in the API layer.
## files
- __init__.py | Empty file with no functionality
## arch
Modular schema organization following FastAPI/Pydantic patterns, with empty __init__.py indicating package initialization for future schema modules.
Standard Python package structure using __init__.py to mark the directory as an importable package, likely intended for request/response models following FastAPI/Pydantic patterns.
## tags
init, empty, functionality
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/schemas/config
## role
Provides Pydantic validation schemas for configuration profile API endpoints, ensuring data integrity for mounts, git URLs, UUIDs, and file paths.
Defines Pydantic validation schemas for configuration profile API request/response models with strict input validation.
## parent
index: apps/api/src/schemas/.pi-map.index.md
map: apps/api/src/schemas/.pi-map.md
+2 -2
View File
@@ -4,12 +4,12 @@ dir: apps/api/src/schemas/config
index: apps/api/src/schemas/config/.pi-map.index.md
## role
Provides Pydantic validation schemas for configuration profile API endpoints, ensuring data integrity for mounts, git URLs, UUIDs, and file paths.
Defines Pydantic validation schemas for configuration profile API request/response models with strict input validation.
## files
- __init__.py | Re-exports Pydantic schemas for configuration profile operations from a submodule to provide a clean public API. | dep: src.schemas.config.config_profile
- config_profile.py | Defines Pydantic request/response schemas for config profile API operations with validation for mounts, git URLs, UUIDs, and file paths. | exp: class:GitMountMapping, class:GitMountItem, class:MountItem, class:ConfigProfileCreate, class:ConfigProfileUpdate, class:ConfigProfileIncludeUpdate, class:ConfigProfileResponse, class:DefaultProfilesUpdate, class:ValidateGitUrlRequest, class:ValidateGitUrlResponse, func:_validate_uuid(v: str | None) → str | None, call:uuid.UUID, raise:ValueError | dep: uuid, pydantic, src.api.shared_validators
## arch
Simple schema-as-code pattern using Pydantic models with field validators; clean public API via explicit re-exports in `__init__.py`.
Standard Python package pattern using `__init__.py` re-exports to expose a clean public API from internal modules, with Pydantic-based schema-per-resource organization.
## tags
profile, config, git, mount, update, validate, response, item
## symbols
@@ -2,7 +2,7 @@
dir: apps/api/src/schemas/project
## role
Provides Pydantic data validation schemas for project-related API endpoints including projects, Git repositories, and SSH keys.
Defines Pydantic data validation schemas for project-related API endpoints, serving as the contract layer between HTTP requests/responses and internal business logic.
## parent
index: apps/api/src/schemas/.pi-map.index.md
map: apps/api/src/schemas/.pi-map.md
+2 -2
View File
@@ -4,14 +4,14 @@ dir: apps/api/src/schemas/project
index: apps/api/src/schemas/project/.pi-map.index.md
## role
Provides Pydantic data validation schemas for project-related API endpoints including projects, Git repositories, and SSH keys.
Defines Pydantic data validation schemas for project-related API endpoints, serving as the contract layer between HTTP requests/responses and internal business logic.
## files
- __init__.py | Re-exports Pydantic schema classes from submodules to provide a unified public API for the project schemas module | dep: src.schemas.project.git_repository, src.schemas.project.project, src.schemas.project.ssh_key
- git_repository.py | Defines Pydantic request/response schemas for Git repository operations in an API. | exp: class:GitRepositoryCreate, class:URLParseRequest, class:URLParseResponse, class:GitRepositoryResponse, class:UpdateSSHKeyRequest, class:FileListResponse, class:FileContentResponse, class:BranchesResponse, class:FileUpdateRequest, class:FileUpdateResponse, class:StatusResponse, class:BranchCreateRequest, class:CheckoutRequest, class:CommitRequest, class:CommitResponse, class:FetchResponse, class:PullResponse, class:PushResponse, class:MergeRequest, class:MergeResponse | dep: uuid, datetime, pydantic
- project.py | Defines Pydantic request/response schemas for project-related API operations. | exp: class:ProjectCreate, class:ProjectUpdate, class:ProjectResponse, class:SetDefaultSSHKeyRequest | dep: uuid, pydantic
- ssh_key.py | Defines Pydantic schemas for SSH key creation, response, signing, and signature verification in an API. | exp: class:SSHKeyCreate, class:SSHKeyResponse, class:SignPayloadRequest, class:SignatureResponse, class:VerifySignatureRequest, class:VerifySignatureResponse | dep: uuid, datetime, pydantic
## arch
Modular schema-per-domain pattern with clean separation of concerns, using Pydantic models for request/response validation and an `__init__.py` facade for unified public API access.
Modular schema decomposition with submodule-per-domain pattern (project, git_repository, ssh_key) aggregated through __init__.py barrel exports, using Pydantic models for declarative validation and serialization.
## tags
response, request, project, create, update, sshkey, pydantic, schemas
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/schemas/system
## role
Provides Pydantic schemas for system health monitoring endpoints in the API.
Provides Pydantic schema definitions for system health monitoring API responses.
## parent
index: apps/api/src/schemas/.pi-map.index.md
map: apps/api/src/schemas/.pi-map.md
+2 -2
View File
@@ -4,12 +4,12 @@ dir: apps/api/src/schemas/system
index: apps/api/src/schemas/system/.pi-map.index.md
## role
Provides Pydantic schemas for system health monitoring endpoints in the API.
Provides Pydantic schema definitions for system health monitoring API responses.
## files
- __init__.py | Re-exports health check schema classes from a submodule to provide a unified interface for the system schemas module. | dep: src.schemas.system.health
- health.py | Defines Pydantic data models for health check API responses including database, disk, and overall system health status. | exp: class:DatabaseHealth, class:DiskHealth, class:HealthChecks, class:HealthResponse, class:DatabaseHealthResponse | dep: pydantic
## arch
Simple submodule pattern with explicit re-exports in __init__.py, using Pydantic models for structured API response validation.
Simple modular schema layer with submodule organization and re-export pattern for clean API surface.
## tags
health, database, response, system, disk, check, schemas, init
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/schemas/tool
## role
Provides Pydantic data validation schemas for tool-related API operations including tool types and instances.
Defines Pydantic data validation schemas for tool instance and tool type API operations in the API layer.
## parent
index: apps/api/src/schemas/.pi-map.index.md
map: apps/api/src/schemas/.pi-map.md
+7 -6
View File
@@ -4,17 +4,18 @@ dir: apps/api/src/schemas/tool
index: apps/api/src/schemas/tool/.pi-map.index.md
## role
Provides Pydantic data validation schemas for tool-related API operations including tool types and instances.
Defines Pydantic data validation schemas for tool instance and tool type API operations in the API layer.
## files
- __init__.py | Re-exports tool-related schema classes from submodules to provide a unified import interface for the tool schemas module. | dep: src.schemas.tool.tool_instance, src.schemas.tool.tool_type
- tool_instance.py | Defines Pydantic request/response schemas for tool instance lifecycle operations (create and start). | exp: class:CreateInstanceRequest, class:StartInstanceRequest | dep: pydantic
- tool_type.py | Defines Pydantic request/response schemas for creating, updating, and validating tool types with Docker compose/dockerfile/manifest definitions | exp: class:ToolTypeCreate, class:ToolTypeUpdate, class:ToolTypeResponse, class:ToolTypeValidateRequest | dep: uuid, datetime, pydantic, src.api.tool.tool_types_validation
- __init__.py | Package initialization file that exposes tool-related schema classes for import convenience. | dep: src.schemas.tool.tool_instance, src.schemas.tool.tool_type
- tool_instance.py | Defines Pydantic request/response schemas for tool instance lifecycle operations (create, create-on-workspace, start). | exp: class:CreateInstanceRequest, class:CreateWorkspaceInstanceRequest, class:StartInstanceRequest | dep: pydantic
- tool_type.py | Defines Pydantic request/response schemas for tool type CRUD operations with conditional validation logic based on definition type (compose/dockerfile/manifest). | exp: class:ToolTypeCreate, class:ToolTypeUpdate, class:ToolTypeResponse, class:ToolTypeValidateRequest | dep: uuid, datetime, pydantic, src.api.tool.tool_types_validation
## arch
Modular schema organization with submodule-per-entity pattern and unified re-export interface via `__init__.py`, following standard Python package structure for clean API imports.
Standard Pydantic schema package pattern with type-specific conditional validation using discriminated unions or field validators based on definition type.
## tags
tool, type, request, instance, schemas, create, pydantic, response
tool, type, request, instance, create, schemas, pydantic, response
## symbols
- CreateInstanceRequest
- CreateWorkspaceInstanceRequest
- StartInstanceRequest
- ToolTypeCreate
- ToolTypeUpdate
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/schemas/user
## role
Provides centralized Pydantic data validation schemas for user-related API requests and responses.
Provides Pydantic data validation schemas for user-related API requests and responses.
## parent
index: apps/api/src/schemas/.pi-map.index.md
map: apps/api/src/schemas/.pi-map.md
+2 -2
View File
@@ -4,13 +4,13 @@ dir: apps/api/src/schemas/user
index: apps/api/src/schemas/user/.pi-map.index.md
## role
Provides centralized Pydantic data validation schemas for user-related API requests and responses.
Provides Pydantic data validation schemas for user-related API requests and responses.
## files
- __init__.py | Re-exports user-related Pydantic schemas from submodules to provide a unified public API for the user schemas package. | dep: src.schemas.user.user, src.schemas.user.user_config
- user.py | Defines Pydantic response and update schemas for user profile data | exp: class:UserProfileResponse, class:UserProfileUpdate | dep: uuid, pydantic
- user_config.py | Defines Pydantic models for user configuration data transfer objects (response and update schemas). | exp: class:UserConfigResponse, class:UserConfigUpdate | dep: pydantic
## arch
Modular package pattern with submodule separation of concerns (user profile vs. user config) and unified public API via `__init__.py` re-exports.
Modular schema organization with submodule separation of concerns and unified package-level re-exports for clean imports.
## tags
user, schemas, response, update, config, pydantic, profile, src
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/scripts
## role
Provides utility scripts for administrative and setup tasks for the API application.
Provides utility scripts for administrative and setup tasks for the API application, specifically database seeding.
## parent
index: apps/api/src/.pi-map.index.md
map: apps/api/src/.pi-map.md
+2 -2
View File
@@ -4,12 +4,12 @@ dir: apps/api/src/scripts
index: apps/api/src/scripts/.pi-map.index.md
## role
Provides utility scripts for administrative and setup tasks for the API application.
Provides utility scripts for administrative and setup tasks for the API application, specifically database seeding.
## files
- __init__.py | Marks the directory as a Python package and provides a docstring describing it as utility scripts for the API package.
- seed.py | Seeds a development user into the database using SQLAlchemy async operations, with idempotency check to avoid duplicates. | exp: func:build_seed_user() → Mapping[str, str | None], func:seed_database(session: AsyncSession) → User, call:build_seed_user, call:session.scalar, call:select(User).where, call:User, call:session.add, call:session.commit, call:session.refresh, func:run() → None, call:SessionLocal, call:seed_database, call:print, call:str, func:main() → None, call:asyncio.run, call:run | dep: collections.abc, sqlalchemy, sqlalchemy.ext.asyncio, src.database, src.models.user, asyncio
## arch
Simple procedural scripts using async SQLAlchemy for database operations, with idempotency guards for safe re-runs.
Simple procedural script architecture with async SQLAlchemy database operations and idempotent initialization patterns.
## tags
seed, user, database, sqlalchemy, package, init, call:build, call:session.scalar
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/seeds
## role
Provides database seeding utilities for initializing built-in tool types in the API application.
Database seeding utilities for populating initial data, specifically built-in tool types.
## parent
index: apps/api/src/.pi-map.index.md
map: apps/api/src/.pi-map.md
+2 -2
View File
@@ -4,12 +4,12 @@ dir: apps/api/src/seeds
index: apps/api/src/seeds/.pi-map.index.md
## role
Provides database seeding utilities for initializing built-in tool types in the API application.
Database seeding utilities for populating initial data, specifically built-in tool types.
## files
- __init__.py | Marks the directory as a Python package for database seeding utilities.
- builtin_tool_types.py | Seeds built-in Docker Compose-based tool types (VS Code Server, Jupyter Notebook, OpenCode) into a database with idempotent create-or-update logic. | exp: func:_table_exists(session, table_name: str) → bool, call:session.execute, call:text, call:result.scalar, func:seed_builtin_tool_types(), call:SessionLocal, call:_table_exists, call:logger.warning, call:session.scalar, call:select(ToolType).where, call:ToolType, call:tool_data.get, call:session.add, call:logger.info, call:session.commit | dep: logging, sqlalchemy, src.database, src.models
## arch
Simple procedural seeding scripts with idempotent create-or-update logic using direct database operations, organized as a Python package with one seed module per entity type.
Simple procedural seeding scripts with idempotent create-or-update logic for Docker Compose-based tool definitions.
## tags
tool, types, table, exists, builtin, call:tool, database, init
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/services
## role
Initializes the services directory as a Python package for business logic modules.
This directory is intended to contain service-layer business logic modules for the API application.
## parent
index: apps/api/src/.pi-map.index.md
map: apps/api/src/.pi-map.md
+2 -2
View File
@@ -4,11 +4,11 @@ dir: apps/api/src/services
index: apps/api/src/services/.pi-map.index.md
## role
Initializes the services directory as a Python package for business logic modules.
This directory is intended to contain service-layer business logic modules for the API application.
## files
- __init__.py | Empty file with no functionality
## arch
Standard Python package structure using empty __init__.py for namespace declaration.
Empty package placeholder following standard Python package structure with no implemented architecture yet.
## tags
init, empty, functionality
## symbols
@@ -2,7 +2,7 @@
dir: apps/api/src/services/config
## role
Provides configuration profile resolution, validation, and CRUD operations for managing hierarchical, mergeable configuration with environment-aware overrides and Git integration.
Provides configuration profile resolution and management services for the API, handling hierarchical config merging, validation, and access control.
## parent
index: apps/api/src/services/.pi-map.index.md
map: apps/api/src/services/.pi-map.md
+2 -2
View File
@@ -4,14 +4,14 @@ dir: apps/api/src/services/config
index: apps/api/src/services/config/.pi-map.index.md
## role
Provides configuration profile resolution, validation, and CRUD operations for managing hierarchical, mergeable configuration with environment-aware overrides and Git integration.
Provides configuration profile resolution and management services for the API, handling hierarchical config merging, validation, and access control.
## files
- __init__.py | Re-exports configuration profile resolution components from a subpackage to provide a unified public API. | dep: src.services.config.config_profile_resolver
- config_profile_resolver.py | Resolves configuration profiles recursively with ordered include merging, cycle detection, and deterministic override rules for environment variables, runtime hints, files, mounts, and git mounts. | exp: class:ConfigProfileCycleError, class:ConfigProfileNotFoundError, class:ResolvedMount, class:ResolvedProfile, func:_detect_cycle(profile_id: uuid.UUID, visited: set[uuid.UUID], path: list[uuid.UUID]) → bool, func:_merge_env_vars(base: dict[str, str], overlay: dict[str, str], overrides: dict[str, str], source_name: str) → dict[str, str], call:dict, call:overlay.items, func:_merge_runtime_hints(base: dict[str, Any], overlay: dict[str, Any], overrides: dict[str, str], source_name: str) → dict[str, Any], call:dict, call:overlay.items, func:_merge_files(base: dict[str, str], overlay: dict[str, str], overrides: dict[str, str], source_name: str) → dict[str, str], call:dict, call:overlay.items, func:_merge_mounts(base: dict[str, ResolvedMount], overlay: list[dict[str, Any]], overrides: dict[str, str], source_name: str) → dict[str, ResolvedMount], call:dict, call:mount_data.get, call:files.items, call:ResolvedMount, func:_merge_git_mounts(base: list[dict[str, Any]], overlay: list[dict[str, Any]], source_name: str) → list[dict[str, Any]], call:list, call:enumerate, call:_normalize_git_mount_entry, call:dict, call:m.get, call:mount.get, call:existing.get, call:existing["mappings"].append, call:existing_sources.add, call:len, call:result.append, func:_normalize_git_mount_entry(entry: dict[str, Any]) → dict[str, Any], call:dict, call:entry.get, call:entry.pop, func:_resolve_profile_recursive(session: AsyncSession, profile_id: uuid.UUID, visited: set[uuid.UUID], path: list[uuid.UUID]) → ResolvedProfile, call:_detect_cycle, call:" -> ".join, call:str, call:session.get, call:ResolvedProfile, call:select(ConfigProfileInclude) .where(ConfigProfileInclude.profile_id == profile_id) .order_by, call:session.execute, call:include_result.scalars().all, call:_resolve_profile_recursive, call:result.included_profiles.append, call:_merge_env_vars, call:_merge_runtime_hints, call:_merge_files, call:_merge_mounts, call:included.mounts.values, call:_merge_git_mounts, raise:ConfigProfileCycleError, raise:ConfigProfileNotFoundError, func:resolve_profile(session: AsyncSession, profile_id: uuid.UUID) → ResolvedProfile, call:_resolve_profile_recursive, call:set, func:check_include_cycle(session: AsyncSession, profile_id: uuid.UUID, new_include_id) → list[uuid.UUID] | None, call:select(ConfigProfileInclude) .where(ConfigProfileInclude.profile_id == current_id) .order_by, call:session.execute, call:include_result.scalars().all, call:_check_from, call:set, call:len, func:_check_from(current_id: uuid.UUID, target_id: uuid.UUID, visited: set[uuid.UUID], path: list[uuid.UUID]) → list[uuid.UUID] | None, call:select(ConfigProfileInclude) .where(ConfigProfileInclude.profile_id == current_id) .order_by, call:session.execute, call:include_result.scalars().all, call:_check_from, func:apply_resolved_profile(instance_dir: str, resolved: ResolvedProfile, home_dir) → tuple[dict[str, str], dict[str, str], list[dict], dict[str, Any]], call:Path, call:dict, call:files.items, call:full_path.resolve().relative_to, call:instance_path.resolve, call:logger.warning, call:full_path.parent.mkdir, call:full_path.write_text, call:resolved.mounts.values, call:expand_container_path, call:expanded_target.lstrip("/").replace, call:mount_dir.mkdir, call:mount.files.items, call:mount_dir.resolve, call:os.path.join, call:volume_mounts.append, call:str, func:expand_container_path(path: str, home_dir: str) → str, call:path.startswith, call:os.path.join, func:resolved_profile_to_dict(resolved: ResolvedProfile) → dict[str, Any], call:str, call:resolved.mounts.values | dep: logging, os, uuid, dataclasses, typing, sqlalchemy, sqlalchemy.ext.asyncio, src.models, pathlib
- crud_service.py | Provides CRUD operations for configuration profiles including validation, access control, size limits, and include cycle detection. | exp: func:calculate_profile_size(data: dict) → int, call:data.get("env_vars", {}).items, call:len, call:key.encode, call:str(value).encode, call:data.get("runtime_hints", {}).items, call:str(mount.get("target", "")).encode, call:str(mount.get("mode", "")).encode, call:mount.get("files", {}).items, call:path.encode, call:content.encode, call:data.get("files", {}).items, func:get_profile_with_includes(session: AsyncSession, profile_id: uuid.UUID) → ConfigProfile | None, call:session.execute, call:select(ConfigProfile) .where(ConfigProfile.id == profile_id) .options, call:selectinload, call:result.scalar_one_or_none, func:check_access(session: AsyncSession, user_id: uuid.UUID, project_id, tool_type_id) → None, call:session.get, raise:HTTPException, func:validate_git_mounts(session: AsyncSession, user_id: uuid.UUID, git_mounts: list[Any], project_id) → None, call:mount.get, call:remote_url.startswith, raise:HTTPException, func:profile_to_response(profile: ConfigProfile, includes) → dict, call:str, call:profile.created_at.isoformat, call:profile.updated_at.isoformat, func:get_or_create_user_config(session: AsyncSession, user_id: uuid.UUID) → UserConfig, call:session.execute, call:select(UserConfig).where, call:result.scalar_one_or_none, call:UserConfig, call:session.add, func:validate_default_profiles(session: AsyncSession, user_id: uuid.UUID, default_profiles: dict[str, str]) → None, call:default_profiles.items, call:uuid.UUID, call:session.get, raise:HTTPException, func:create_profile(session: AsyncSession, user_id: uuid.UUID, data: Any) → ConfigProfile, call:session.execute, call:select(ConfigProfile) .where( ConfigProfile.user_id == user_id, ConfigProfile.name == data.name, ) .options, call:selectinload, call:existing.scalar_one_or_none, call:uuid.UUID, call:check_access, call:m.model_dump, call:hasattr, call:validate_git_mounts, call:calculate_profile_size, call:data.model_dump, call:ConfigProfile, call:session.add, call:session.commit, call:select(ConfigProfile) .where(ConfigProfile.id == profile.id) .options, call:result.scalar_one, raise:HTTPException, func:update_profile(session: AsyncSession, profile: ConfigProfile, data: Any) → ConfigProfile, call:data.model_dump, call:session.execute, call:select(ConfigProfile).where, call:existing.scalar_one_or_none, call:uuid.UUID, call:check_access, call:m.model_dump, call:hasattr, call:validate_git_mounts, call:profile_to_response, call:calculate_profile_size, call:update_data.items, call:isinstance, call:setattr, call:session.commit, call:select(ConfigProfile) .where(ConfigProfile.id == profile.id) .options, call:selectinload, call:result.scalar_one, raise:HTTPException, func:update_includes(session: AsyncSession, profile: ConfigProfile, included_ids: list[uuid.UUID], user_id: uuid.UUID) → ConfigProfile, call:session.get, call:check_include_cycle, call:" -> ".join, call:str, call:session.execute, call:select(ConfigProfileInclude).where, call:result.scalars().all, call:session.delete, call:session.flush, call:enumerate, call:ConfigProfileInclude, call:session.add, call:session.commit, call:select(ConfigProfile).where, call:result.scalar_one, raise:HTTPException | dep: uuid, typing, fastapi, sqlalchemy, sqlalchemy.ext.asyncio, sqlalchemy.orm, src.models, src.models.project, src.services.config.config_profile_resolver
- resolver_service.py | Resolves default configuration profiles for users/projects/tools and validates Git URLs with SSH key support. | exp: func:resolve_default_profile(session: AsyncSession, user_id: uuid.UUID, project_id: uuid.UUID, tool_type_id: uuid.UUID) → dict, call:select(ConfigProfile) .where(ConfigProfile.user_id == user_id) .where( (ConfigProfile.project_id.is_(None) & ConfigProfile.tool_type_id.is_(None)) | (ConfigProfile.project_id == project_id) | (ConfigProfile.tool_type_id == tool_type_id) | ( (ConfigProfile.project_id == project_id) & (ConfigProfile.tool_type_id == tool_type_id) ) ) .order_by, call:ConfigProfile.project_id.is_, call:ConfigProfile.tool_type_id.is_, call:session.execute, call:result.scalars().all, call:str, func:validate_git_url(session: AsyncSession, current_user_id: uuid.UUID, url: str, ssh_key_id: str | None) → ValidateGitUrlResponse, call:parse_git_url, call:url.strip, call:parse_result.get, call:ValidateGitUrlResponse, call:uuid.UUID, call:session.get, call:_get_fernet, call:fernet.decrypt(ssh_key.private_key_encrypted.encode()).decode, call:ssh_key.private_key_encrypted.encode, call:tempfile.mkstemp, call:os.write, call:private_key.encode, call:os.close, call:os.chmod, call:subprocess.run, call:os.path.exists, call:os.unlink, call:result.stderr.strip, call:stderr.lower, call:result.stdout.strip().split, call:line.strip, call:line.split, call:len, call:ref.startswith, call:branches.append | dep: logging, os, subprocess, uuid, typing, fastapi, sqlalchemy, sqlalchemy.ext.asyncio, src.models, src.services.shared.ssh_keys, src.utils.git_url_parser, src.schemas.config, tempfile
## arch
Layered service architecture with separation between resolution logic (recursive merge with cycle detection), CRUD operations (validation, access control, limits), and default resolution (user/project/tool scoping, Git/SSH integration), exposing a unified public API through `__init__.py` facade pattern.
Service-layer pattern with separation of concerns: dedicated resolver (recursive merge with cycle detection), CRUD operations (validation/ACLs), and default resolution (user/project/tool scoping); supports multiple config sources with deterministic override precedence.
## tags
profile, call:, call:select, git, merge, call:str, call:session.execute, mounts
## symbols
@@ -2,7 +2,7 @@
dir: apps/api/src/services/docker
## role
Provides Docker-based infrastructure services for container orchestration, configuration management, runtime operations, and secure tunneling to expose internal services.
Provides Docker infrastructure services for container lifecycle management, compose orchestration, configuration deployment, and secure tunneling to expose internal services.
## parent
index: apps/api/src/services/.pi-map.index.md
map: apps/api/src/services/.pi-map.md
+2 -2
View File
@@ -4,7 +4,7 @@ dir: apps/api/src/services/docker
index: apps/api/src/services/docker/.pi-map.index.md
## role
Provides Docker-based infrastructure services for container orchestration, configuration management, runtime operations, and secure tunneling to expose internal services.
Provides Docker infrastructure services for container lifecycle management, compose orchestration, configuration deployment, and secure tunneling to expose internal services.
## files
- __init__.py | Package initialization file that exposes Docker-related service functions for container operations, compose management, configuration staging, and tunnel management. | dep: src.services.docker.compose, src.services.docker.config_staging, src.services.docker.container, src.services.docker.tunnel
- compose.py | Generates, renders, and executes Docker Compose commands for container orchestration with volume sorting and template substitution. | exp: func:sort_volumes_by_specificity(volumes: list[str]) → list[str], call:vol.split, call:len, call:parts[1].rstrip, call:target.count, call:targets.append, call:Counter(targets).items, call:logger.warning, call:sorted, func:_target_depth(vol: str) → int, call:vol.split, call:len, call:parts[1].rstrip, call:target.count, func:render_compose_template(template: str, variables: dict[str, Any]) → str, call:variables.items, call:result.replace, call:str, func:write_compose_file(instance_dir: str, content: str) → str, call:Path, call:compose_path.write_text, call:str, func:execute_compose_command(compose_path: str, action: str, timeout, env_file) → tuple[int, str, str], call:Path, call:cmd.extend, call:cmd.append, call:subprocess.run, call:str, raise:ValueError | dep: logging, subprocess, collections, pathlib, typing, collections.Counter, pathlib.Path, typing.Any
@@ -12,7 +12,7 @@ Provides Docker-based infrastructure services for container orchestration, confi
- container.py | Provides Docker container runtime queries and network management utilities via subprocess calls to the Docker CLI. | exp: func:get_container_id(instance_name: str) → str | None, call:instance_name.lower, call:subprocess.run, call:result.stdout.strip, call:ps_result.stdout.strip().splitlines, call:line.split, call:len, call:name.lower, func:get_container_name(instance_name: str) → str | None, call:subprocess.run, call:instance_name.lower, call:result.stdout.strip().lstrip, func:get_backend_network_name() → str, call:subprocess.run, call:result.stdout.strip().split, call:net.lower, func:connect_container_to_network(container_name: str, network_name) → bool, call:get_backend_network_name, call:subprocess.run, func:get_container_ip_on_network(container_id: str, network_name) → str | None, call:get_backend_network_name, call:subprocess.run, call:result.stdout.strip, func:is_container_on_network(container_id: str, network_name) → bool, call:get_backend_network_name, call:subprocess.run, func:get_container_status(container_id: str) → dict[str, Any], call:subprocess.run, call:result.stdout.strip().split, call:int, call:len, call:parts[1].isdigit, func:wait_for_container_running(container_id: str, timeout, interval) → dict[str, Any], call:time.time, call:get_container_status, call:time.sleep, func:get_container_logs(container_id: str, tail) → str, call:subprocess.run, call:str, func:find_free_port(start, end) → int, call:range, call:socket.socket, call:s.connect_ex, raise:RuntimeError | dep: logging, subprocess, time, typing, socket
- tunnel.py | Manages Cloudflare tunnels by orchestrating cloudflared Docker containers to expose internal services via temporary public URLs. | exp: func:_tunnel_container_name(instance_name: str) → str, call:instance_name.lower, func:_ensure_image() → None, call:subprocess.run, call:result.stdout.strip, call:logger.info, call:logger.warning, func:_cleanup_stale_tunnel(tunnel_name: str) → None, call:subprocess.run, func:_get_tunnel_logs(tunnel_name: str) → tuple[str, str], call:subprocess.run, func:_get_tunnel_exit_code(tunnel_name: str) → int | None, call:subprocess.run, call:int, call:result.stdout.strip, func:start_tunnel(instance_name: str, container_port: int, timeout, target_url) → dict[str, str], call:_ensure_image, call:_tunnel_container_name, call:_cleanup_stale_tunnel, call:instance_name.lower, call:get_backend_network_name, call:logger.debug, call:" ".join, call:subprocess.run, call:proc.stdout.strip, call:re.compile, call:__import__("time").time, call:_get_tunnel_logs, call:url_pattern.search, call:match.group, call:_get_tunnel_exit_code, call:__import__("time").sleep, call:logger.info, raise:RuntimeError, func:stop_tunnel(instance_name: str) → None, call:_tunnel_container_name, call:_cleanup_stale_tunnel, call:logger.debug, func:recreate_tunnel(instance_name: str, container_port: int, target_url) → dict[str, str], call:stop_tunnel, call:start_tunnel, func:check_tunnel_health(url: str, timeout) → dict[str, Any], call:subprocess.run, call:int, call:result.stdout.strip, call:str(exc).lower, call:any | dep: logging, re, subprocess, typing, src.services.docker.container
## arch
Modular service-oriented architecture with subprocess-based Docker CLI integration, Jinja2 templating for compose generation, path-traversal-safe file staging, and Cloudflare tunnel orchestration via containerized cloudflared.
Subprocess-based CLI wrapper architecture around Docker/cloudflared tools with template rendering, path-traversal-safe file staging, and functional decomposition into single-responsibility modules.
## tags
tunnel, container, call:subprocess.run, get, name, call:, network, call:result.stdout.strip
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/services/git
## role
Provides git repository operations for workspace management including cloning, authentication, and common git commands
Encapsulates all Git version control operations for workspace management, providing both synchronous and asynchronous interfaces for repository cloning, commit history, branch management, and remote operations with SSH authentication support.
## parent
index: apps/api/src/services/.pi-map.index.md
map: apps/api/src/services/.pi-map.md
+2 -2
View File
@@ -4,7 +4,7 @@ dir: apps/api/src/services/git
index: apps/api/src/services/git/.pi-map.index.md
## role
Provides git repository operations for workspace management including cloning, authentication, and common git commands
Encapsulates all Git version control operations for workspace management, providing both synchronous and asynchronous interfaces for repository cloning, commit history, branch management, and remote operations with SSH authentication support.
## files
- __init__.py | Exports the public API for the git services module by re-exporting key classes and functions from submodules. | dep: src.services.git.clone, src.services.git.git_operations, src.services.git.git_service
- clone.py | Provides git repository cloning with optional SSH authentication, dirty state checking, and cleanup utilities | exp: func:clone_repository(remote_url: str, ssh_key_path: str | None, instance_dir: str, branch) → str, call:Path, call:clone_path.mkdir, call:os.environ.copy, call:str, call:logger.debug, call:subprocess.run, call:logger.error, raise:RuntimeError, func:check_dirty_state(clone_path: str) → tuple[bool, list[str]], call:subprocess.run, call:logger.warning, call:line.strip, call:result.stdout.split, call:len, func:remove_clone_directory(instance_dir: str) → None, call:Path, call:clone_path.exists, call:shutil.rmtree, call:logger.debug | dep: logging, os, subprocess, pathlib, shutil
@@ -12,7 +12,7 @@ Provides git repository operations for workspace management including cloning, a
- git_service.py | Provides asynchronous and synchronous git operations (clone, fetch, pull, branch check) with SSH key support for workspace management. | exp: class:GitService | dep: asyncio, logging, os, subprocess, tempfile
- operations.py | Provides git repository operations including cloning, initialization, remote validation, and branch listing with SSH key authentication support. | exp: func:get_repo_path(user_id: uuid.UUID, project_id: uuid.UUID, name: str) → str, call:Settings, call:os.path.join, call:str, func:build_provider_clone_url(owner: str, repo: str) → str, func:prepare_ssh_env(ssh_key: SSHKey | None) → tuple[dict, str] | None, call:_get_fernet, call:fernet.decrypt(ssh_key.private_key_encrypted.encode()).decode, call:ssh_key.private_key_encrypted.encode, call:tempfile.mkstemp, call:os.write, call:private_key.encode, call:os.close, call:os.chmod, func:preflight_remote_repository(remote_url: str, ssh_key) → None, call:prepare_ssh_env, call:subprocess.run, call:os.path.exists, call:os.unlink, call:logger.error, raise:HTTPException, func:clone_working_repository(remote_url: str, repo_path: str, ssh_key) → None, call:prepare_ssh_env, call:subprocess.run, call:os.path.exists, call:os.unlink, call:logger.error, raise:HTTPException, func:init_working_repository(repo_path: str) → None, call:subprocess.run, raise:HTTPException, func:list_remote_branches(remote_url: str, ssh_key) → tuple[list[str], str], call:prepare_ssh_env, call:subprocess.run, call:logger.warning, call:result.stdout.strip().split, call:line.split, call:len, call:ref.startswith, call:branches.append, call:str, call:os.path.exists, call:os.unlink, raise:RuntimeError | dep: logging, os, subprocess, uuid, fastapi, src.config, src.models, src.services.shared.ssh_keys, tempfile
## arch
Layered service architecture with operation decomposition across specialized modules (clone, operations, git_operations, git_service), wrapping git CLI with async/sync variants and SSH key-based authentication
Layered abstraction pattern with three implementation tiers: low-level CLI wrappers (git_operations.py, operations.py), mid-level service coordinators (git_service.py), and high-level specialized utilities (clone.py), unified through __init__.py re-exports to present a single public API surface.
## tags
git, raise:runtime, error, run, call:self., clone, call:subprocess.run, ssh
## symbols
+1 -1
View File
@@ -11,7 +11,7 @@ Provides infrastructure for managing tool instance lifecycle events, health moni
- health_monitor.py | Background health monitor that periodically polls Docker container and tunnel health for tool instances, publishing state change events and notifications. | exp: class:HealthSnapshot, class:HealthMonitor, method:__init__(self, event_bus: InstanceEventBus) → None, method:start(self) → None, call:self._task.done, call:asyncio.get_running_loop, call:loop.create_task, call:self._poll_loop, method:stop(self) → None, call:self._task.done, call:self._task.cancel, call:self._last_known_state.clear, method:_poll_loop(self) → None, call:asyncio.sleep, call:self._run_check_cycle, call:logger.exception, method:_run_check_cycle(self) → None, call:SessionLocal, call:session.execute, call:select(ToolInstance).where, call:ToolInstance.status.in_, call:result.scalars().all, call:self._check_instance, method:_check_instance(self, session: AsyncSession, instance: ToolInstance) → None, call:logger.debug, call:get_container_status, call:logger.exception, call:str, call:get_correlation_id, call:check_tunnel_health, call:tunnel_result.get, call:HealthSnapshot, call:self._last_known_state.get, call:self._derive_status, call:self._snapshots_equal, call:self._handle_state_change, method:_derive_status(self, snapshot: HealthSnapshot, previous: HealthSnapshot | None, current_status: str | None) → str, method:_snapshots_equal(self, a: HealthSnapshot, b: HealthSnapshot) → bool, method:_handle_state_change(self, session: AsyncSession, instance: ToolInstance, previous: HealthSnapshot | None, snapshot: HealthSnapshot, new_status: str) → None, call:HealthCheck, call:session.add, call:session.commit, call:get_correlation_id, call:str, call:datetime.now(timezone.utc).isoformat, call:self._event_bus.publish, call:notification_service.create_notification, call:logger.exception | dep: asyncio, logging, uuid, dataclasses, datetime, sqlalchemy, sqlalchemy.ext.asyncio, src.database, src.models, src.services.shared.correlation, src.services.docker, src.services.shared.tunnel, src.services.instance.event_bus, src.services.shared.notification_service
- lifecycle_hooks.py | Provides helpers to publish tool instance lifecycle events, persist audit records, and conditionally send user notifications. | exp: func:_derive_title(event_type: str) → str, call:mapping.get, call:event_type.replace("instance.", "").replace("_", " ").title, func:_should_notify(event_type: str, status: str | None) → bool, func:_build_payload(event_type: str, instance: ToolInstance, status, message, metadata) → InstanceEventPayload, call:str, call:datetime.now(timezone.utc).isoformat, call:get_correlation_id, func:_write_audit_row(session: AsyncSession, instance: ToolInstance, event_type: str, created_by, status, message, metadata) → InstanceEvent, call:InstanceEvent, call:event_type.replace, call:session.add, call:session.commit, func:publish_lifecycle_event(event_bus: InstanceEventBus, session: AsyncSession, instance: ToolInstance, event_type: str, created_by, status, message, metadata) → None, call:_build_payload, call:_write_audit_row, call:event_bus.publish, call:_should_notify, call:_derive_title, call:notification_service.create_notification, call:logger.exception, call:payload.get | dep: logging, uuid, datetime, sqlalchemy.ext.asyncio, src.models, src.services.shared.correlation, src.services.instance.event_bus, src.services.shared.notification_service
## arch
Event-driven architecture using a singleton-typed in-memory pub/sub event bus with decoupled background health monitoring, lifecycle hook orchestration, and exception-isolated sync/async callback handling.
Event-driven architecture using a singleton in-memory pub/sub event bus with typed messages, background polling workers, and lifecycle hooks that bridge domain events to persistence and notifications with exception isolation between sync/async handlers.
## tags
call:self., instance, src, services, event, health, call:logger.exception, check
## symbols
@@ -2,7 +2,7 @@
dir: apps/api/src/services/shared
## role
Provides reusable, cross-cutting infrastructure services for the API including I/O safety, container operations, user notifications, request tracing, and workspace lifecycle management.
Provides reusable, cross-cutting infrastructure services for security, I/O, container operations, and workspace management used throughout the API layer.
## parent
index: apps/api/src/services/.pi-map.index.md
map: apps/api/src/services/.pi-map.md
+4 -4
View File
@@ -4,7 +4,7 @@ dir: apps/api/src/services/shared
index: apps/api/src/services/shared/.pi-map.index.md
## role
Provides reusable, cross-cutting infrastructure services for the API including I/O safety, container operations, user notifications, request tracing, and workspace lifecycle management.
Provides reusable, cross-cutting infrastructure services for security, I/O, container operations, and workspace management used throughout the API layer.
## files
- __init__.py | Re-exports shared service classes and functions from a services package to provide a unified public API | dep: src.services.shared.correlation, src.services.shared.file_service, src.services.shared.notification_service, src.services.shared.permission_fixer, src.services.shared.readiness_probe, src.services.shared.ssh_keys, src.services.shared.tunnel, src.services.shared.workspace_manager, correlation, file_service, notification_service, permission_fixer, readiness_probe, ssh_keys, tunnel, workspace_manager
- correlation.py | Provides async correlation ID tracking via context variables and FastAPI middleware for request tracing. | exp: class:CorrelationIdMiddleware, method:dispatch(self, request: Request, call_next), call:request.headers.get, call:str, call:uuid.uuid4, call:CORRELATION_ID.set, call:call_next, call:CORRELATION_ID.reset, func:get_correlation_id() → str, call:CORRELATION_ID.get, call:str, call:uuid.uuid4 | dep: contextvars, uuid, fastapi, starlette.middleware.base, fastapi.Request, starlette.middleware.base.BaseHTTPMiddleware
@@ -14,11 +14,11 @@ Provides reusable, cross-cutting infrastructure services for the API including I
- readiness_probe.py | Executes a retryable readiness probe command inside a Docker container with configurable timeout and interval | exp: func:execute_probe(container_id: str, command: str, timeout, interval) → tuple[bool, list[str]], call:asyncio.get_event_loop().time, call:logs.append, call:logger.debug, call:subprocess.run, call:result.stdout.strip, call:result.stderr.strip, call:asyncio.sleep | dep: asyncio, logging, subprocess
- ssh_keys.py | Decrypts and writes SSH key files to instance directories for container mounting, with optional ownership configuration and SSH config generation. | exp: func:_get_fernet() → Fernet, call:Settings, call:hashlib.sha256(settings.session_secret.encode()).digest, call:settings.session_secret.encode, call:base64.urlsafe_b64encode, call:Fernet, func:_sanitize_filename(name: str) → str, call:re.sub, call:sanitized.strip, func:prepare_ssh_key_files(instance_dir: str, ssh_key, subdir, uid, gid, key_filename, write_config) → str, call:Path, call:ssh_dir.mkdir, call:_get_fernet, call:fernet.decrypt(ssh_key.private_key_encrypted.encode()).decode, call:ssh_key.private_key_encrypted.encode, call:private_key_path.write_text, call:os.chmod, call:public_key_path.write_text, call:config_path.write_text, call:os.chown, call:logger.debug, call:logger.warning, call:os.getuid, call:str, func:write_ssh_config(ssh_dir: str, key_filenames: list[str], uid, gid) → None, call:Path, call:ssh_dir_path.mkdir, call:lines.append, call:"\n".join, call:config_path.write_text, call:os.chmod, call:os.chown, func:cleanup_ssh_key_files(instance_dir: str) → None, call:Path, call:ssh_dir.exists, call:ssh_dir.iterdir, call:file_path.unlink, call:ssh_dir.rmdir | dep: logging, os, re, pathlib, cryptography.fernet, src.config, base64, hashlib
- tunnel.py | Re-exports Docker tunnel functions from a nested module for backward compatibility. | dep: src.services.docker.tunnel
- workspace_manager.py | Manages workspace lifecycle operations including creation, deletion, synchronization, and validation for git repository workspaces. | exp: class:SyncResult, class:WorkspaceHasInstancesError, method:__init__(self, instances: list[dict]) → None, call:super().__init__, call:len, class:WorkspaceManager, method:_workspace_path(self, repo_id: uuid.UUID, name: str) → str, call:os.path.join, call:str, method:create(self, repo: GitRepository, user_id: uuid.UUID, name: str, branch, session) → Workspace, call:self._workspace_path, call:os.path.dirname, call:os.makedirs, call:contextlib.suppress, call:os.chmod, call:logger.info, call:os.path.exists, call:logger.warning, call:shutil.rmtree, call:getattr, call:session.execute, call:select(SSHKey).where, call:result.scalar_one_or_none, call:_get_fernet, call:fernet.decrypt( ssh_key_obj.private_key_encrypted.encode() ).decode, call:ssh_key_obj.private_key_encrypted.encode, call:GitService.clone, call:self._make_world_writable, call:Workspace, call:datetime.now, raise:ValueError, method:delete(self, workspace: Workspace, force, session) → None, call:self._get_instances, call:self._stop_and_delete_instance, call:os.path.exists, call:shutil.rmtree, call:logger.info, call:session.delete, raise:ValueError, raise:WorkspaceHasInstancesError, method:sync(self, workspace: Workspace, session) → SyncResult, call:logger.info, call:session.get, call:getattr, call:session.execute, call:select(SSHKey).where, call:result.scalar_one_or_none, call:_get_fernet, call:fernet.decrypt( ssh_key_obj.private_key_encrypted.encode() ).decode, call:ssh_key_obj.private_key_encrypted.encode, call:GitService.fetch, call:GitService.branch_exists_remotely, call:SyncResult, call:GitService.pull, call:self._make_world_writable, call:datetime.now, method:_make_world_writable(self, path: str) → None, call:contextlib.suppress, call:os.chmod, call:os.walk, call:os.path.join, call:os.stat, method:_get_instances(self, workspace: Workspace, session: AsyncSession) → list[ToolInstance], call:session.execute, call:select(ToolInstance).where, call:list, call:result.scalars().all, method:_stop_and_delete_instance(self, instance: ToolInstance) → None, call:logger.warning | dep: contextlib, logging, os, shutil, stat, uuid, dataclasses, datetime, typing, sqlalchemy, src.models, src.services.git.git_service, src.services.shared.ssh_keys, sqlalchemy.ext.asyncio
- workspace_manager.py | Manages Git workspace lifecycle operations including creation, deletion, sync, and migration of legacy tool instances into workspace-bound repositories. | exp: class:SyncResult, class:WorkspaceHasInstancesError, method:__init__(self, instances: list[dict]) → None, call:super().__init__, call:len, class:WorkspaceManager, method:_workspace_path(self, repo_id: uuid.UUID, name: str) → str, call:os.path.join, call:str, method:create(self, repo: GitRepository, user_id: uuid.UUID, name: str, branch, session) → Workspace, call:self._workspace_path, call:os.path.dirname, call:os.makedirs, call:contextlib.suppress, call:os.chmod, call:logger.info, call:os.path.exists, call:logger.warning, call:shutil.rmtree, call:getattr, call:session.execute, call:select(SSHKey).where, call:result.scalar_one_or_none, call:_get_fernet, call:fernet.decrypt( ssh_key_obj.private_key_encrypted.encode() ).decode, call:ssh_key_obj.private_key_encrypted.encode, call:GitService.clone, call:self._make_world_writable, call:Workspace, call:datetime.now, raise:ValueError, method:delete(self, workspace: Workspace, force, session) → None, call:self._get_instances, call:self._stop_and_delete_instance, call:os.path.exists, call:shutil.rmtree, call:logger.info, call:session.delete, raise:ValueError, raise:WorkspaceHasInstancesError, method:sync(self, workspace: Workspace, session) → SyncResult, call:logger.info, call:session.get, call:getattr, call:session.execute, call:select(SSHKey).where, call:result.scalar_one_or_none, call:_get_fernet, call:fernet.decrypt( ssh_key_obj.private_key_encrypted.encode() ).decode, call:ssh_key_obj.private_key_encrypted.encode, call:GitService.fetch, call:GitService.branch_exists_remotely, call:SyncResult, call:GitService.pull, call:self._make_world_writable, call:datetime.now, method:_make_world_writable(self, path: str) → None, call:contextlib.suppress, call:os.chmod, call:os.walk, call:os.path.join, call:os.stat, method:_get_instances(self, workspace: Workspace, session: AsyncSession) → list[ToolInstance], call:session.execute, call:select(ToolInstance).where, call:list, call:result.scalars().all, method:_stop_and_delete_instance(self, instance: ToolInstance, session: AsyncSession) → None, call:delete_tool_instance, call:logger.info, call:logger.error, method:ensure_instance_workspace(self, instance: ToolInstance, session: AsyncSession) → Workspace, call:session.get, call:self._workspace_name_exists, call:self._migrate_clone_into_workspace, call:self.create, call:session.add, call:session.commit, call:session.refresh, call:logger.info, raise:RuntimeError, method:_workspace_name_exists(self, session: AsyncSession, repo_id: uuid.UUID, name: str) → bool, call:session.execute, call:select(Workspace).where, call:result.scalar_one_or_none, method:_migrate_clone_into_workspace(self, instance: ToolInstance, repo: "GitRepository", session: AsyncSession, name: str) → Workspace, call:os.path.dirname, call:os.path.join, call:os.path.exists, call:self._workspace_path, call:os.makedirs, call:contextlib.suppress, call:os.chmod, call:shutil.rmtree, call:shutil.move, call:self._make_world_writable, call:Workspace, call:datetime.now, call:session.add, call:session.flush, raise:RuntimeError | dep: contextlib, logging, os, shutil, stat, uuid, dataclasses, datetime, typing, sqlalchemy, src.models, src.services.git.git_service, src.services.shared.ssh_keys, sqlalchemy.ext.asyncio, src.services.tool.instance_service
## arch
Modular service-oriented architecture with async singletons, context variable-based state propagation, path traversal defense, Docker container exec abstraction, and strict ownership-based isolation boundaries.
Modular utility services pattern with async singletons, context variables for request tracing, defensive security (path traversal/ownership isolation), Docker exec abstraction, and Git-backed workspace lifecycle management.
## tags
error, get, key, call:self., src, call:ssh, at.is, call:session.execute
error, workspace, call:self., get, key, src, call:session.execute, call:ssh
## symbols
- CorrelationIdMiddleware
- FileEntry
@@ -2,7 +2,7 @@
dir: apps/api/src/services/terminal
## role
Provides backend WebSocket terminal session management with PTY-based interactive shells, lifecycle control, and real-time I/O streaming for remote terminal access.
Provides WebSocket-connected terminal session management with PTY-based I/O for remote terminal access in the API server.
## parent
index: apps/api/src/services/.pi-map.index.md
map: apps/api/src/services/.pi-map.md
+2 -2
View File
@@ -4,13 +4,13 @@ dir: apps/api/src/services/terminal
index: apps/api/src/services/terminal/.pi-map.index.md
## role
Provides backend WebSocket terminal session management with PTY-based interactive shells, lifecycle control, and real-time I/O streaming for remote terminal access.
Provides WebSocket-connected terminal session management with PTY-based I/O for remote terminal access in the API server.
## files
- __init__.py | Package initialization file that exports the public API for a terminal services module | dep: src.services.terminal.terminal_manager, src.services.terminal.terminal_session
- terminal_manager.py | Manages WebSocket-connected terminal sessions with lifecycle control, idle cleanup, database persistence, and per-instance session limits. | exp: class:MaxSessionsExceededError, method:__init__(self, instance_id: str, max_sessions) → None, call:super().__init__, class:TerminalManager, method:__init__(self) → None, call:self._start_idle_check, method:_start_idle_check(self) → None, call:self._idle_check_task.done, call:asyncio.get_running_loop, call:loop.create_task, call:self._idle_check_loop, method:_idle_check_loop(self) → None, call:asyncio.sleep, call:self._cleanup_idle_sessions, call:logger.error, method:_cleanup_idle_sessions(self) → None, call:list, call:self._sessions.items, call:session.is_idle, call:idle_keys.append, call:logger.info, call:self._sessions.pop, call:session.close, call:asyncio.create_task, call:self._mark_closed_in_db, method:_insert_db_session_row(self, session_id: str, instance_id: uuid.UUID, name: str) → None, call:SessionLocal, call:pg_insert(TerminalSessionModel) .values( id=uuid.UUID(session_id), instance_id=instance_id, name=name, status="active", created_at=datetime.now(timezone.utc), last_activity_at=datetime.now(timezone.utc), ) .on_conflict_do_nothing, call:uuid.UUID, call:datetime.now, call:db_session.execute, call:db_session.commit, call:logger.debug, call:logger.error, method:_mark_closed_in_db(self, session_id: str) → None, call:SessionLocal, call:db_session.get, call:uuid.UUID, call:datetime.now, call:db_session.commit, call:logger.debug, call:logger.error, method:_count_sessions_for_instance(self, instance_id_str: str) → int, call:sum, method:create_session(self, instance_id: uuid.UUID, container_id: str, startup_command, name, session_id) → TerminalSession, call:str, call:self._count_sessions_for_instance, call:uuid.uuid4, call:TerminalSession, call:session.start, call:asyncio.create_task, call:self._insert_db_session_row, call:logger.info, raise:MaxSessionsExceededError, method:get_or_create_session(self, instance_id: uuid.UUID, container_id: str, startup_command) → TerminalSession, call:self._start_idle_check, call:str, call:session.is_alive, call:logger.debug, call:session.close, call:logger.info, call:uuid.uuid4, call:TerminalSession, call:session.start, call:asyncio.create_task, call:self._insert_db_session_row, method:get_session(self, instance_id: str, session_id: str) → TerminalSession | None, call:self._sessions.get, call:self._sessions.items, method:_find_key_by_internal_id(self, instance_id: str, internal_session_id: str) → tuple[str, str] | None, call:self._sessions.items, method:get_sessions_for_instance(self, instance_id: str) → list[TerminalSession], call:self._sessions.items, method:close_session(self, instance_id: str, session_id: str) → None, call:self._sessions.pop, call:session.close, call:asyncio.create_task, call:self._mark_closed_in_db, call:logger.info, method:attach_websocket(self, session: TerminalSession, websocket: WebSocket) → None, call:session.has_websockets, call:logger.debug, call:list, call:ws.close, call:session._websockets.clear, call:session.attach_websocket, call:session.get_buffer, call:websocket.send_bytes, method:detach_websocket(self, session: TerminalSession, websocket: WebSocket) → None, call:session.detach_websocket, method:reset_session(self, instance_id: uuid.UUID, container_id: str, startup_command, session_id, name) → TerminalSession, call:str, call:logger.debug, call:self._sessions.pop, call:old_session.close, call:asyncio.create_task, call:self._mark_closed_in_db, call:uuid.uuid4, call:TerminalSession, call:new_session.start, call:self._insert_db_session_row, method:close_all(self) → None, call:list, call:self._sessions.values, call:self._sessions.clear, call:session.close, call:self._idle_check_task.done, call:self._idle_check_task.cancel | dep: asyncio, logging, uuid, datetime, fastapi, sqlalchemy.dialects.postgresql, src.database, src.models, src.services.terminal.terminal_session, fastapi.WebSocket
- terminal_session.py | Manages a high-performance asyncio-native terminal session using PTY I/O with event-driven reads, output batching, and flow control for WebSocket delivery. | exp: class:TerminalSession, method:__init__(self, session_id: str, instance_id: uuid.UUID, container_id: str, startup_command, name) → None, call:deque, call:set, call:time.time, call:self._generate_name, call:str, call:bytearray, call:asyncio.Lock, method:start(self, startup_command) → None, call:pty.openpty, call:self._set_terminal_size, call:logger.debug, call:asyncio.create_subprocess_exec, call:os.close, call:time.time, call:self._start_reading, method:_start_reading(self) → None, call:asyncio.get_event_loop, call:loop.add_reader, call:logger.debug, call:logger.error, method:_stop_reading(self) → None, call:asyncio.get_event_loop, call:loop.remove_reader, method:_on_fd_readable(self) → None, call:os.read, call:logger.debug, call:self._handle_eof, call:self._add_to_buffer, call:time.time, call:self._queue_output, method:_add_to_buffer(self, data: bytes) → None, call:self._output_buffer.append, call:len, call:self._output_buffer.popleft, method:_queue_output(self, data: bytes) → None, call:self._batch_buffer.extend, call:len, call:self._pause_output, call:asyncio.get_event_loop, call:loop.call_later, method:_flush_batch_sync(self) → None, call:self._batch_buffer.clear, call:bytes, call:set, call:list, call:asyncio.create_task, call:self._send_bytes, call:dead_sockets.add, method:_send_bytes(self, ws: Any, payload: bytes) → None, call:ws.send_bytes, call:self._websockets.discard, method:acknowledge_data(self, char_count: int) → None, call:max, call:self._resume_output, call:self._ack_timeout_handle.cancel, call:asyncio.get_event_loop, call:loop.call_later, method:_ack_timeout_fallback(self) → None, call:logger.warning, call:self._resume_output, method:_pause_output(self) → None, call:self._stop_reading, call:logger.debug, method:_resume_output(self) → None, call:self._start_reading, call:logger.debug, method:get_buffer(self) → bytes, call:b"".join, method:_handle_eof(self) → None, call:self._stop_reading, call:self.process._transport.close, call:set, call:self._websockets.clear, call:asyncio.create_task, call:ws.close, call:logger.info, method:write_input(self, data: bytes) → None, call:os.write, call:time.time, call:logger.debug, call:self._handle_eof, method:_set_terminal_size(self, cols: int, rows: int) → None, call:logger.warning, call:struct.pack, call:fcntl.ioctl, call:logger.debug, call:logger.error, method:resize(self, cols: int, rows: int) → None, call:logger.warning, call:logger.debug, call:self._set_terminal_size, call:os.kill, method:reset(self) → None, call:self.close, call:self._output_buffer.clear, call:self._websockets.clear, call:self._batch_buffer.clear, method:close(self) → None, call:self._stop_reading, call:self._batch_timer.cancel, call:self._ack_timeout_handle.cancel, call:os.close, call:self.process.kill, call:asyncio.wait_for, call:self.process.wait, method:is_alive(self) → bool, method:is_idle(self) → bool, call:time.time, method:attach_websocket(self, websocket: Any) → None, call:self._websockets.add, call:time.time, method:detach_websocket(self, websocket: Any) → None, call:self._websockets.discard, method:has_websockets(self) → bool, call:len, method:send_to_all(self, data: bytes) → None, call:set, call:ws.send_bytes, call:dead_sockets.add, call:self._websockets.discard, method:read_output(self) → bytes | dep: asyncio, logging, os, pty, signal, struct, fcntl, time, uuid, collections, typing, collections.deque
## arch
Asyncio-native event-driven architecture with PTY subprocess I/O, batched output with flow control, session lifecycle management (idle cleanup, persistence, limits), and WebSocket message passing.
Asyncio-native event-driven architecture with session lifecycle management, resource cleanup, output batching/flow control, and database persistence for scalable terminal multiplexing.
## tags
call:self., session, call:logger.debug, idle, output, terminal, check, task
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/services/tool
## role
Orchestrates Docker container lifecycle for tool instances with git repository mounting, configuration validation, and SSH tunnel management.
Provides Docker container lifecycle management for tool instances with git repository integration and configuration validation.
## parent
index: apps/api/src/services/.pi-map.index.md
map: apps/api/src/services/.pi-map.md
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/src/utils
## role
Provides Git repository interaction utilities for the API layer, abstracting subprocess-based git operations into reusable Python modules.
Provides Git repository interaction utilities that wrap subprocess commands for URL parsing, file browsing, history extraction, and repository control operations.
## parent
index: apps/api/src/.pi-map.index.md
map: apps/api/src/.pi-map.md
+2 -2
View File
@@ -4,7 +4,7 @@ dir: apps/api/src/utils
index: apps/api/src/utils/.pi-map.index.md
## role
Provides Git repository interaction utilities for the API layer, abstracting subprocess-based git operations into reusable Python modules.
Provides Git repository interaction utilities that wrap subprocess commands for URL parsing, file browsing, history extraction, and repository control operations.
## files
- __init__.py | Empty file with no functionality
- git_control.py | Provides a Python wrapper for common Git repository operations using subprocess calls | exp: class:GitStatus, func:_run_git_command(repo_path: str, *args: str) → str, call:subprocess.run, raise:RuntimeError, func:get_status(repo_path: str) → GitStatus, call:_run_git_command(repo_path, "rev-parse", "--abbrev-ref", "HEAD").strip, call:_run_git_command(repo_path, "symbolic-ref", "--short", "HEAD").strip, call:GitStatus, call:output.strip().split, call:line.startswith, call:branch_info.split("[ahead ")[1].split, call:int, call:ahead_str.split, call:branch_info.split("[behind ")[1].split, call:behind_str.split, call:len, call:status.untracked.append, call:status.added.append, call:status.deleted.append, call:status.renamed.append, call:status.modified.append, func:create_branch(repo_path: str, name: str, base_branch) → None, call:_run_git_command, call:str(e).lower, func:delete_branch(repo_path: str, name: str, force) → None, call:_run_git_command, func:checkout_branch(repo_path: str, name: str) → None, call:_run_git_command, call:str(e).lower, func:commit_changes(repo_path: str, message: str, author_name: str, author_email: str, files) → str, call:_run_git_command(repo_path, "rev-parse", "HEAD").strip, func:fetch(repo_path: str) → None, call:_run_git_command, func:pull(repo_path: str, branch) → None, call:args.append, call:_run_git_command, func:push(repo_path: str, branch) → None, call:args.extend, call:_run_git_command, func:merge(repo_path: str, source_branch: str, target_branch, message) → str, call:checkout_branch, call:args.extend, call:_run_git_command(repo_path, "rev-parse", "HEAD").strip, func:get_current_branch(repo_path: str) → str, call:_run_git_command(repo_path, "rev-parse", "--abbrev-ref", "HEAD").strip, call:_run_git_command(repo_path, "symbolic-ref", "--short", "HEAD").strip | dep: subprocess, dataclasses
@@ -12,7 +12,7 @@ Provides Git repository interaction utilities for the API layer, abstracting sub
- git_history.py | Extracts and structures git commit history, metadata, diffs, and graph visualization data from bare/mirror repositories using subprocess git commands. | exp: class:Commit, class:FileChange, class:CommitDetail, func:_run_git_command(repo_path: str, args: list[str]) → str, call:subprocess.run, raise:RuntimeError, func:get_commit_history(repo_path: str, branch, limit, offset) → dict[str, Any], call:_run_git_command, call:b.strip, call:branches_output.strip().split, call:log_args.append, call:_get_branch_map, call:_get_tag_map, call:log_output.strip().split, call:line.strip, call:line.split, call:len, call:parts[1].split, call:commits.append, call:Commit, call:int, call:branch_map.get, call:tag_map.get, call:count_output.strip, call:_build_graph_data, call:enumerate, call:min, call:commit_dicts.append, call:_commit_to_dict, func:get_commit_detail(repo_path: str, commit_hash: str) → dict[str, Any], call:_run_git_command, call:log_output.strip().split, call:len, call:parts[1].split, call:int, call:_parse_stats, call:_parse_diff, call:_get_branch_map, call:_get_tag_map, call:datetime.fromtimestamp(timestamp, tz=timezone.utc).isoformat, call:branch_map.get, call:tag_map.get, call:_file_change_to_dict, raise:ValueError, func:_get_branch_map(repo_path: str) → dict[str, list[str]], call:_run_git_command, call:branch_output.strip().split, call:line.split, call:result[commit_hash].append, func:_get_tag_map(repo_path: str) → dict[str, list[str]], call:_run_git_command, call:tag_output.strip().split, call:line.split, call:result[commit_hash].append, func:_build_graph_data(commits: list[Commit]) → dict[str, Any], call:enumerate, call:hash, call:nodes.append, call:edges.append, func:_parse_stats(stat_output: str) → dict[str, int], call:stat_output.strip().split, call:line.strip, call:line.split, call:part.strip, call:int, call:part.split, func:_parse_diff(diff_output: str) → list[FileChange], call:diff_output.split, call:line.startswith, call:"\n".join, call:files.append, call:FileChange, call:current_diff.append, func:_commit_to_dict(commit: Commit, graph_symbol, graph_depth) → dict[str, Any], call:refs.extend, call:datetime.fromtimestamp(commit.timestamp, tz=timezone.utc).isoformat, func:_file_change_to_dict(file_change: FileChange) → dict[str, Any] | dep: subprocess, dataclasses, datetime, typing
- git_url_parser.py | Parses various Git hosting service URLs (browser, SSH, HTTPS) to extract normalized base repository clone URLs with .git suffix. | exp: func:extract_base_repo_url(url: str) → str | None, call:url.startswith, call:url.endswith, call:urlparse, call:parsed.netloc.lower, call:parsed.path.split, call:_extract_github_url, call:_extract_gitlab_url, call:_extract_bitbucket_url, call:_extract_generic_url, func:_extract_github_url(url: str, path_parts: list[str]) → str | None, call:len, call:repo_name.endswith, func:_extract_gitlab_url(url: str, path_parts: list[str]) → str | None, call:len, call:repo_name.endswith, func:_extract_bitbucket_url(url: str, path_parts: list[str]) → str | None, call:len, call:repo_name.endswith, func:_extract_generic_url(url: str, path_parts: list[str]) → str | None, call:len, call:repo_name.endswith, call:urlparse, func:is_valid_clone_url(url: str) → bool, call:url.startswith, call:urlparse, call:path.endswith, func:parse_git_url(url: str) → dict, call:url.strip, call:urlparse, call:parsed.netloc.lower, call:url.startswith, call:url.split, call:len, call:parts[0].replace, call:is_valid_clone_url, call:extract_base_repo_url | dep: urllib.parse
## arch
Utility-layer architecture with functional decomposition into single-responsibility modules (operations, file browsing, history extraction, URL parsing), all relying on subprocess calls to external git binary rather than native git libraries.
Facade pattern with subprocess-based adapters, where each module encapsulates a distinct Git domain (control, files, history, URLs) behind Pythonic function interfaces.
## tags
call:, git, run, command, get, url, commit, call:len
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/tests
## role
Provides shared test infrastructure and fixtures for the FastAPI API application.
Provides shared test infrastructure and fixtures for API integration testing.
## parent
index: apps/api/.pi-map.index.md
map: apps/api/.pi-map.md
+4 -4
View File
@@ -4,13 +4,13 @@ dir: apps/api/tests
index: apps/api/tests/.pi-map.index.md
## role
Provides shared test infrastructure and fixtures for the FastAPI API application.
Provides shared test infrastructure and fixtures for API integration testing.
## files
- conftest.py | Provides shared pytest fixtures for FastAPI testing with async SQLite database, authenticated clients, and test data setup. | exp: func:test_client() → Generator[TestClient, None, None], call:create_async_engine, call:engine.begin, call:conn.run_sync, call:asyncio.run, call:init_db, call:async_sessionmaker, call:patch, call:TestClient, call:app.dependency_overrides.pop, call:engine.dispose, func:init_db(), call:engine.begin, call:conn.run_sync, func:override_get_db_session() → AsyncGenerator[AsyncSession, None], call:async_sessionmaker, func:db_session(test_client) → AsyncGenerator[AsyncSession, None], call:app.dependency_overrides.get, call:override_fn, call:gen.asend, call:gen.aclose, call:create_async_engine, call:engine.begin, call:conn.run_sync, call:async_sessionmaker, call:engine.dispose, func:authenticated_client(test_client) → Generator[TestClient, None, None], call:str, call:uuid.uuid4, call:Settings, call:app.dependency_overrides.get, call:override_fn, call:gen.asend, call:User, call:uuid.UUID, call:session.add, call:session.commit, call:gen.aclose, call:asyncio.run, call:create_test_user, call:create_session_cookie, call:test_client.cookies.set, func:create_test_user(), call:app.dependency_overrides.get, call:override_fn, call:gen.asend, call:User, call:uuid.UUID, call:session.add, call:session.commit, call:gen.aclose, func:test_project_and_repo(authenticated_client) → tuple[str, str], call:uuid.uuid4, call:Settings, call:authenticated_client.cookies.get, call:decode_session_cookie, call:uuid.UUID, call:asyncio.run, call:get_user_id, call:app.dependency_overrides.get, call:override_fn, call:gen.asend, call:Project, call:session.add, call:GitRepository, call:session.commit, call:gen.aclose, call:create_project_and_repo, call:str, raise:RuntimeError, func:get_user_id(), call:Settings, call:authenticated_client.cookies.get, call:decode_session_cookie, call:uuid.UUID, func:create_project_and_repo(), call:app.dependency_overrides.get, call:override_fn, call:gen.asend, call:Project, call:session.add, call:GitRepository, call:session.commit, call:gen.aclose, func:admin_client(test_client) → Generator[TestClient, None, None], call:str, call:uuid.uuid4, call:Settings, call:app.dependency_overrides.get, call:override_fn, call:gen.asend, call:User, call:uuid.UUID, call:session.add, call:session.commit, call:gen.aclose, call:asyncio.run, call:create_admin_user, call:create_session_cookie, call:test_client.cookies.set, func:create_admin_user(), call:app.dependency_overrides.get, call:override_fn, call:gen.asend, call:User, call:uuid.UUID, call:session.add, call:session.commit, call:gen.aclose | dep: asyncio, os, typing, unittest.mock, pytest, pytest_asyncio, fastapi.testclient, sqlalchemy.ext.asyncio, src.config, src.models.base, src.main, src.auth.dependencies, uuid, src.auth.session, src.models.user, src.models.project, src.models.git_repository, fastapi, sqlalchemy, src.models, src.auth
- conftest.py | Provides shared pytest fixtures for testing a FastAPI application with async SQLite database, authenticated clients, and test data setup. | exp: func:test_client() → Generator[TestClient, None, None], call:create_async_engine, call:engine.begin, call:conn.run_sync, call:asyncio.run, call:init_db, call:async_sessionmaker, call:patch, call:TestClient, call:app.dependency_overrides.pop, call:engine.dispose, func:init_db(), call:engine.begin, call:conn.run_sync, func:override_get_db_session() → AsyncGenerator[AsyncSession, None], call:async_sessionmaker, func:db_session(test_client) → AsyncGenerator[AsyncSession, None], call:app.dependency_overrides.get, call:override_fn, call:gen.asend, call:gen.aclose, call:create_async_engine, call:engine.begin, call:conn.run_sync, call:async_sessionmaker, call:engine.dispose, func:authenticated_client(test_client) → Generator[TestClient, None, None], call:str, call:uuid.uuid4, call:Settings, call:app.dependency_overrides.get, call:override_fn, call:gen.asend, call:User, call:uuid.UUID, call:session.add, call:session.commit, call:gen.aclose, call:asyncio.run, call:create_test_user, call:create_session_cookie, call:test_client.cookies.set, func:create_test_user(), call:app.dependency_overrides.get, call:override_fn, call:gen.asend, call:User, call:uuid.UUID, call:session.add, call:session.commit, call:gen.aclose, func:test_project_and_repo(authenticated_client) → tuple[str, str], call:uuid.uuid4, call:Settings, call:authenticated_client.cookies.get, call:decode_session_cookie, call:uuid.UUID, call:asyncio.run, call:get_user_id, call:app.dependency_overrides.get, call:override_fn, call:gen.asend, call:Project, call:session.add, call:GitRepository, call:session.commit, call:gen.aclose, call:create_project_and_repo, call:str, raise:RuntimeError, func:get_user_id(), call:Settings, call:authenticated_client.cookies.get, call:decode_session_cookie, call:uuid.UUID, func:create_project_and_repo(), call:app.dependency_overrides.get, call:override_fn, call:gen.asend, call:Project, call:session.add, call:GitRepository, call:session.commit, call:gen.aclose, func:admin_client(test_client) → Generator[TestClient, None, None], call:str, call:uuid.uuid4, call:Settings, call:app.dependency_overrides.get, call:override_fn, call:gen.asend, call:User, call:uuid.UUID, call:session.add, call:session.commit, call:gen.aclose, call:asyncio.run, call:create_admin_user, call:create_session_cookie, call:test_client.cookies.set, func:create_admin_user(), call:app.dependency_overrides.get, call:override_fn, call:gen.asend, call:User, call:uuid.UUID, call:session.add, call:session.commit, call:gen.aclose | dep: asyncio, os, typing, unittest.mock, pytest, pytest_asyncio, fastapi.testclient, sqlalchemy.ext.asyncio, src.config, src.models.base, src.main, src.auth.dependencies, uuid, src.auth.session, src.models.user.user, src.models.project.project, src.models.project.git_repository, fastapi, sqlalchemy, aiosqlite, src.models, src.auth
## arch
Pytest fixture-based testing architecture with async SQLite database setup, authenticated HTTP client factories, and test data seeding patterns.
Pytest fixture-based testing architecture with async SQLite database lifecycle management, FastAPI TestClient dependency injection, and authenticated client wrappers for role-based testing.
## tags
call:app.dependency, call:create, overrides.get, call:override, fn, call:gen.asend, call:gen.aclose, session
call:app.dependency, call:create, overrides.get, call:override, fn, call:gen.asend, call:gen.aclose, user
## symbols
- test_client
- init_db
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/tests/api
## role
Integration test suite for API authentication and multi-session WebSocket terminal functionality.
Integration tests for multi-session terminal WebSocket routes and authentication requirements on REST API endpoints
## parent
index: apps/api/tests/.pi-map.index.md
map: apps/api/tests/.pi-map.md
+2 -2
View File
@@ -4,11 +4,11 @@ dir: apps/api/tests/api
index: apps/api/tests/api/.pi-map.index.md
## role
Integration test suite for API authentication and multi-session WebSocket terminal functionality.
Integration tests for multi-session terminal WebSocket routes and authentication requirements on REST API endpoints
## files
- test_terminal_ws_multi.py | Integration tests verifying multi-session terminal WebSocket routes exist and REST API endpoints require authentication | exp: class:TestTerminalWebSocketMultiSession, method:test_specific_session_websocket_route_exists(self, client), call:client.get, method:test_default_session_alias_route_exists(self, client), call:client.get, class:TestTerminalRestApi, method:test_list_sessions_requires_auth(self, client), call:client.get, method:test_create_session_requires_auth(self, client), call:client.post, method:test_close_session_requires_auth(self, client), call:client.delete, method:test_reset_session_requires_auth(self, client), call:client.post, method:test_rename_session_requires_auth(self, client), call:client.post, method:test_legacy_reset_alias_requires_auth(self, client), call:client.post, func:client(), call:TestClient | dep: pytest, fastapi.testclient, src.main
## arch
pytest-based integration testing with FastAPI TestClient, WebSocket endpoint verification, and REST API authentication requirement validation.
Test-driven validation using pytest with WebSocket client testing and HTTP authentication assertion patterns
## tags
test, session, requires, auth, call:client.post, terminal, call:client.get, multi
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/tests/integration
## role
Integration and unit test suite for the FastAPI backend API, covering authentication, CRUD APIs, workspace/git operations, and event/notification systems using real databases and external dependencies.
Integration test suite for the API backend, covering authentication, workspaces, projects, notifications, configuration, and database models with real PostgreSQL and git repositories.
## parent
index: apps/api/tests/.pi-map.index.md
map: apps/api/tests/.pi-map.md
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/tests/services
## role
Unit tests for verifying TerminalManager's multi-session terminal lifecycle and resource management capabilities.
Unit tests for TerminalManager's multi-session functionality and session lifecycle management.
## parent
index: apps/api/tests/.pi-map.index.md
map: apps/api/tests/.pi-map.md
+3 -3
View File
@@ -4,11 +4,11 @@ dir: apps/api/tests/services
index: apps/api/tests/services/.pi-map.index.md
## role
Unit tests for verifying TerminalManager's multi-session terminal lifecycle and resource management capabilities.
Unit tests for TerminalManager's multi-session functionality and session lifecycle management.
## files
- test_terminal_manager_multi.py | Unit tests for TerminalManager's multi-session support including session creation limits, instance filtering, websocket attachment behavior, default session handling, and idle cleanup. | exp: class:FakeWebSocket, method:__init__(self, name) → None, method:close(self, code, reason) → None, method:send_bytes(self, data: bytes) → None, call:self._sent.append, func:manager() → TerminalManager, call:TerminalManager, call:tm._idle_check_task.done, call:tm._idle_check_task.cancel, func:mock_terminal_session(monkeypatch) → None, call:__import__("time").time, call:monkeypatch.setattr, func:fake_start(self), call:__import__("time").time, func:instance_id() → uuid.UUID, call:uuid.uuid4, func:test_create_session_increases_count(manager: TerminalManager, mock_terminal_session, instance_id: uuid.UUID) → None, call:len, call:manager.get_sessions_for_instance, call:str, call:manager.create_session, func:test_create_session_enforces_max_5(manager: TerminalManager, mock_terminal_session, instance_id: uuid.UUID) → None, call:range, call:manager.create_session, call:len, call:manager.get_sessions_for_instance, call:str, call:pytest.raises, func:test_get_sessions_for_instance_filters_by_instance(manager: TerminalManager, mock_terminal_session) → None, call:uuid.uuid4, call:manager.create_session, call:len, call:manager.get_sessions_for_instance, call:str, func:test_close_session_removes_from_dict(manager: TerminalManager, mock_terminal_session, instance_id: uuid.UUID) → None, call:manager.create_session, call:manager.get_session, call:str, call:patch.object, call:AsyncMock, call:manager.close_session, call:asyncio.sleep, call:mock_mark.assert_called_once_with, func:test_attach_websocket_only_closes_same_session(manager: TerminalManager, mock_terminal_session, instance_id: uuid.UUID) → None, call:manager.create_session, call:FakeWebSocket, call:session_a.attach_websocket, call:session_b.attach_websocket, call:manager.attach_websocket, func:test_default_session_keyed_separately(manager: TerminalManager, mock_terminal_session, instance_id: uuid.UUID) → None, call:manager.get_or_create_session, call:manager.create_session, call:manager.get_session, call:str, func:test_idle_cleanup_updates_db_status(manager: TerminalManager, mock_terminal_session, instance_id: uuid.UUID) → None, call:manager.create_session, call:patch.object, call:AsyncMock, call:manager._cleanup_idle_sessions, call:manager.get_session, call:str, call:mock_mark.assert_called_once_with | dep: asyncio, uuid, unittest.mock, pytest, src.services.terminal_manager, src.services.terminal_session
- test_terminal_manager_multi.py | Unit tests for TerminalManager's multi-session support including session creation limits, instance filtering, WebSocket attachment behavior, default session handling, and idle cleanup. | exp: class:FakeWebSocket, method:__init__(self, name) → None, method:close(self, code, reason) → None, method:send_bytes(self, data: bytes) → None, call:self._sent.append, func:manager() → TerminalManager, call:TerminalManager, call:tm._idle_check_task.done, call:tm._idle_check_task.cancel, func:mock_terminal_session(monkeypatch) → None, call:__import__("time").time, call:monkeypatch.setattr, func:fake_start(self), call:__import__("time").time, func:instance_id() → uuid.UUID, call:uuid.uuid4, func:test_create_session_increases_count(manager: TerminalManager, mock_terminal_session, instance_id: uuid.UUID) → None, call:len, call:manager.get_sessions_for_instance, call:str, call:manager.create_session, func:test_create_session_enforces_max_5(manager: TerminalManager, mock_terminal_session, instance_id: uuid.UUID) → None, call:range, call:manager.create_session, call:len, call:manager.get_sessions_for_instance, call:str, call:pytest.raises, func:test_get_sessions_for_instance_filters_by_instance(manager: TerminalManager, mock_terminal_session) → None, call:uuid.uuid4, call:manager.create_session, call:len, call:manager.get_sessions_for_instance, call:str, func:test_close_session_removes_from_dict(manager: TerminalManager, mock_terminal_session, instance_id: uuid.UUID) → None, call:manager.create_session, call:manager.get_session, call:str, call:patch.object, call:AsyncMock, call:manager.close_session, call:asyncio.sleep, call:mock_mark.assert_called_once_with, func:test_attach_websocket_only_closes_same_session(manager: TerminalManager, mock_terminal_session, instance_id: uuid.UUID) → None, call:manager.create_session, call:FakeWebSocket, call:session_a.attach_websocket, call:session_b.attach_websocket, call:manager.attach_websocket, func:test_default_session_keyed_separately(manager: TerminalManager, mock_terminal_session, instance_id: uuid.UUID) → None, call:manager.get_or_create_session, call:manager.create_session, call:manager.get_session, call:str, func:test_idle_cleanup_updates_db_status(manager: TerminalManager, mock_terminal_session, instance_id: uuid.UUID) → None, call:manager.create_session, call:patch.object, call:AsyncMock, call:manager._cleanup_idle_sessions, call:manager.get_session, call:str, call:mock_mark.assert_called_once_with | dep: asyncio, uuid, unittest.mock, pytest, src.services.terminal.terminal_manager, src.services.terminal.terminal_session
## arch
Pytest-based test suite using fixture mocking for async service dependencies and parameterized scenarios for session limit boundary testing.
pytest-based test suite with mocked dependencies, testing session limits, filtering, WebSocket handling, and background cleanup tasks.
## tags
session, test, call:manager.get, call:manager.create, instance, call:str, sessions, websocket
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/tests/system
## role
System-level integration test suite for the API application.
System-level integration tests for the API application
## parent
index: apps/api/tests/.pi-map.index.md
map: apps/api/tests/.pi-map.md
+2 -2
View File
@@ -4,11 +4,11 @@ dir: apps/api/tests/system
index: apps/api/tests/system/.pi-map.index.md
## role
System-level integration test suite for the API application.
System-level integration tests for the API application
## files
- __init__.py | Empty file with no functionality
## arch
Minimal test package structure with placeholder initialization, following Python package conventions for future test module organization.
Standard Python test package structure with empty initializer for module discovery
## tags
init, empty, functionality
## symbols
+1 -5
View File
@@ -2,7 +2,7 @@
dir: apps/api/tests/unit
## role
Unit test suite for the API backend, covering configuration, Docker operations, Git services, file handling, health monitoring, notifications, and SSH key management.
Contains comprehensive unit tests for the API application's core services, utilities, and infrastructure components.
## parent
index: apps/api/tests/.pi-map.index.md
map: apps/api/tests/.pi-map.md
@@ -16,11 +16,7 @@ map: apps/api/tests/.pi-map.md
- test_docker_service.py
- test_event_bus.py
- test_file_service.py
- test_git_mount_resolution.py
- test_git_mounts.py
- test_git_operations.py
- test_git_repository_clone_preflight.py
- test_git_repository_working_clones.py
- test_git_service.py
- test_git_url_parser.py
- test_health_monitor.py
+20 -24
View File
@@ -4,37 +4,33 @@ dir: apps/api/tests/unit
index: apps/api/tests/unit/.pi-map.index.md
## role
Unit test suite for the API backend, covering configuration, Docker operations, Git services, file handling, health monitoring, notifications, and SSH key management.
Contains comprehensive unit tests for the API application's core services, utilities, and infrastructure components.
## files
- __init__.py | Empty file with no functionality
- test_config.py | Unit tests for application configuration settings, database URL construction, and environment-specific behavior | exp: func:test_settings_default_database_url_uses_asyncpg() → None, call:Settings, func:test_build_database_url_uses_explicit_values() → None, call:build_database_url, func:test_settings_prefers_explicit_database_url_env(monkeypatch) → None, call:monkeypatch.setenv, call:Settings, func:test_auth_settings_have_secure_defaults() → None, call:Settings, call:settings.resolved_authentik_authorize_url.endswith, call:settings.resolved_authentik_token_url.endswith, call:settings.resolved_authentik_jwks_url.endswith, func:test_cookie_policy_is_strict_in_production(monkeypatch) → None, call:monkeypatch.setenv, call:Settings, func:test_cookie_policy_is_relaxed_for_local_dev(monkeypatch) → None, call:monkeypatch.setenv, call:Settings | dep: pytest, src.config, src.database
- test_config_profile_resolver.py | Unit tests for configuration profile resolution, including merge functions, profile inheritance with includes, cycle detection, and git mount normalization. | exp: class:TestMergeFunctions, method:test_merge_env_vars_basic(self) → None, call:_merge_env_vars, method:test_merge_env_vars_tracks_overrides(self) → None, call:_merge_env_vars, method:test_merge_runtime_hints_basic(self) → None, call:_merge_runtime_hints, method:test_merge_files_basic(self) → None, call:_merge_files, method:test_merge_mounts_basic(self) → None, call:_merge_mounts, method:test_merge_mounts_file_override(self) → None, call:_merge_mounts, call:ResolvedMount, method:test_merge_mounts_mode_conflict(self) → None, call:_merge_mounts, call:ResolvedMount, method:test_merge_git_mounts_basic(self) → None, call:_merge_git_mounts, call:len, method:test_merge_git_mounts_concatenate_same_repo_branch(self) → None, call:_merge_git_mounts, call:len, method:test_merge_git_mounts_dedup_same_mapping(self) → None, call:_merge_git_mounts, call:len, method:test_merge_git_mounts_different_repos(self) → None, call:_merge_git_mounts, call:len, method:test_merge_git_mounts_different_branches(self) → None, call:_merge_git_mounts, call:len, call:m.get, class:TestResolveProfile, class:TestApplyResolvedProfile, method:test_mounts_individual_files_not_directory(self, tmp_path) → None, call:ResolvedProfile, call:uuid.uuid4, call:ResolvedMount, call:apply_resolved_profile, call:str, call:len, method:test_file_mount_preserves_sibling_files(self, tmp_path) → None, call:ResolvedProfile, call:uuid.uuid4, call:ResolvedMount, call:apply_resolved_profile, call:str, call:len, call:volumes[0]["source"].endswith, method:test_empty_mount_produces_no_volumes(self, tmp_path) → None, call:ResolvedProfile, call:uuid.uuid4, call:ResolvedMount, call:apply_resolved_profile, call:str, method:test_home_expansion_in_file_mount_target(self, tmp_path) → None, call:ResolvedProfile, call:uuid.uuid4, call:ResolvedMount, call:apply_resolved_profile, call:str, class:TestCheckIncludeCycle | dep: uuid, pytest, sqlalchemy.ext.asyncio, src.models.config_profile, src.services.config_profile_resolver
- test_docker_build.py | Unit tests for a Docker image build service that validates successful builds, failures, command structure, file writing, context handling, path traversal prevention, timeouts, and exceptions. | exp: class:TestBuildImage | dep: subprocess, tempfile, pathlib, unittest.mock, pytest, src.services.docker_build
- test_docker_service.py | Unit tests for Docker service utility functions including container ID/name retrieval and volume sorting by mount specificity. | exp: class:TestGetContainerId, class:TestGetContainerName, class:TestSortVolumesBySpecificity, method:test_parent_before_child(self) → None, call:sort_volumes_by_specificity, method:test_stable_sort_for_equal_depth(self) → None, call:sort_volumes_by_specificity, method:test_with_type_suffix(self) → None, call:sort_volumes_by_specificity, method:test_empty_list(self) → None, call:sort_volumes_by_specificity, method:test_single_volume(self) → None, call:sort_volumes_by_specificity, method:test_duplicate_target_warning(self, caplog) → None, call:caplog.at_level, call:sort_volumes_by_specificity | dep: unittest.mock, logging, src.services.docker, subprocess
- test_event_bus.py | Unit tests for InstanceEventBus verifying publish/subscribe behavior, exception isolation, unsubscribe functionality, and async callback support | exp: func:event_bus() → InstanceEventBus, call:InstanceEventBus, call:bus._reset_for_testing, func:sample_payload() → InstanceEventPayload, call:str, call:uuid.uuid4, func:test_publish_delivers_to_all_subscribers(event_bus: InstanceEventBus, sample_payload: InstanceEventPayload) → None, call:received.append, call:event_bus.subscribe, call:event_bus.publish, call:len, func:callback_1(payload: InstanceEventPayload) → None, call:received.append, func:callback_2(payload: InstanceEventPayload) → None, call:received.append, func:callback_3(payload: InstanceEventPayload) → None, call:received.append, func:test_subscriber_exception_isolation(event_bus: InstanceEventBus, sample_payload: InstanceEventPayload) → None, call:received.append, call:event_bus.subscribe, call:event_bus.publish, raise:RuntimeError, func:bad_callback(_payload: InstanceEventPayload) → None, raise:RuntimeError, func:good_callback(_payload: InstanceEventPayload) → None, call:received.append, func:test_unsubscribe_removes_callback(event_bus: InstanceEventBus, sample_payload: InstanceEventPayload) → None, call:received.append, call:event_bus.subscribe, call:unsubscribe, call:event_bus.publish, func:callback(_payload: InstanceEventPayload) → None, call:received.append, func:test_publish_to_empty_subscriber_list(event_bus: InstanceEventBus, sample_payload: InstanceEventPayload) → None, call:event_bus.publish, func:test_async_subscriber_supported(event_bus: InstanceEventBus, sample_payload: InstanceEventPayload) → None, call:asyncio.sleep, call:received.append, call:event_bus.subscribe, call:event_bus.publish, func:async_callback(_payload: InstanceEventPayload) → None, call:asyncio.sleep, call:received.append, func:test_unsubscribe_all_clears_subscribers(event_bus: InstanceEventBus, sample_payload: InstanceEventPayload) → None, call:received.append, call:event_bus.subscribe, call:event_bus.unsubscribe_all, call:event_bus.publish, func:callback(_payload: InstanceEventPayload) → None, call:received.append | dep: asyncio, uuid, typing, pytest, src.services.event_bus
- test_file_service.py | Unit tests for FileService validating directory listing, file read/write, binary rejection, and path traversal prevention. | exp: class:TestFileService, method:test_list_directory_empty(self, temp_workspace: Workspace), call:FileService, call:service.list_directory, method:test_list_directory_with_files(self, temp_workspace: Workspace), call:os.makedirs, call:os.path.join, call:open, call:f.write, call:FileService, call:service.list_directory, call:len, method:test_read_file(self, temp_workspace: Workspace), call:open, call:os.path.join, call:f.write, call:FileService, call:service.read_file, method:test_read_binary_file_rejected(self, temp_workspace: Workspace), call:open, call:os.path.join, call:f.write, call:FileService, call:pytest.raises, call:service.read_file, method:test_write_file(self, temp_workspace: Workspace), call:FileService, call:service.write_file, call:os.path.exists, call:os.path.join, call:open, call:f.read, method:test_path_escapes_workspace(self, temp_workspace: Workspace), call:FileService, call:pytest.raises, call:service.list_directory, func:temp_workspace(), call:tempfile.TemporaryDirectory, call:Workspace | dep: os, tempfile, pytest, src.models, src.services.shared.file_service, src.models.Workspace, src.services.shared.file_service.FileService
- test_git_mount_resolution.py | Unit tests for git mount resolution functions including glob expansion, branch checkout, and mount validation in tool instances. | exp: class:TestExpandGlobSource, method:test_no_glob_single_file(self, tmp_path: Path) → None, call:test_file.write_text, call:_expand_glob_source, call:str, call:len, method:test_no_glob_missing_file(self, tmp_path: Path) → None, call:_expand_glob_source, call:str, call:len, method:test_glob_pattern(self, tmp_path: Path) → None, call:(tmp_path / "file1.txt").write_text, call:(tmp_path / "file2.txt").write_text, call:(tmp_path / "other.py").write_text, call:_expand_glob_source, call:str, call:len, call:all, call:f.endswith, method:test_glob_recursive(self, tmp_path: Path) → None, call:subdir.mkdir, call:(subdir / "nested.txt").write_text, call:_expand_glob_source, call:str, call:len, method:test_glob_limit_enforced(self, tmp_path: Path) → None, call:range, call:(tmp_path / f"file{i}.txt").write_text, call:_expand_glob_source, call:str, call:len, method:test_glob_escapes_repo(self, tmp_path: Path) → None, call:other_dir.mkdir, call:(other_dir / "outside.txt").write_text, call:_expand_glob_source, call:str, call:all, call:r.startswith, class:TestCheckoutBranch, method:test_checkout_existing_branch(self, tmp_path: Path) → None, call:os.system, call:(tmp_path / "file.txt").write_text, call:_checkout_branch, call:str, call:os.popen(f"cd {tmp_path} && git branch --show-current").read().strip, method:test_checkout_nonexistent_branch(self, tmp_path: Path) → None, call:os.system, call:(tmp_path / "file.txt").write_text, call:_checkout_branch, call:str, class:TestResolveSingleGitMount | dep: os, pathlib, pytest, src.api.tool_instances, pathlib.Path
- test_git_mounts.py | Unit tests for git mount resolution functions that handle multi-mapping support, normalization, glob expansion, and Docker volume bind mounting. | exp: class:TestNormalizeGitMount, method:test_legacy_to_mappings(self) → None, call:_normalize_git_mount, method:test_already_mappings(self) → None, call:_normalize_git_mount, method:test_missing_target_path_no_mappings(self) → None, call:_normalize_git_mount, class:TestResolveGitMountMappings, method:test_single_mapping(self) → None, call:tempfile.TemporaryDirectory, call:os.makedirs, call:os.path.join, call:_resolve_git_mount_mappings, call:len, method:test_multiple_mappings(self) → None, call:tempfile.TemporaryDirectory, call:os.makedirs, call:os.path.join, call:_resolve_git_mount_mappings, call:len, method:test_relative_target_path(self) → None, call:tempfile.TemporaryDirectory, call:os.makedirs, call:os.path.join, call:_resolve_git_mount_mappings, call:len, method:test_glob_expansion(self) → None, call:tempfile.TemporaryDirectory, call:os.makedirs, call:os.path.join, call:_resolve_git_mount_mappings, call:len, method:test_missing_target_path_skipped(self) → None, call:tempfile.TemporaryDirectory, call:_resolve_git_mount_mappings, call:len, method:test_no_working_directory_for_relative_target(self) → None, call:tempfile.TemporaryDirectory, call:os.makedirs, call:os.path.join, call:_resolve_git_mount_mappings, call:len, class:TestResolveSingleGitMount, class:TestExpandGlobSource, method:test_no_glob(self) → None, call:tempfile.TemporaryDirectory, call:os.path.join, call:open(path, "w").close, call:_expand_glob_source, method:test_no_glob_missing(self) → None, call:tempfile.TemporaryDirectory, call:os.path.join, call:_expand_glob_source, method:test_glob_pattern(self) → None, call:tempfile.TemporaryDirectory, call:open(os.path.join(tmp, "a.txt"), "w").close, call:os.path.join, call:open(os.path.join(tmp, "b.txt"), "w").close, call:_expand_glob_source, call:len | dep: os, tempfile, unittest.mock, pytest, src.api.tool_instances
- test_git_operations.py | Unit tests for GitOperations class covering git status, commit, history, and branch operations | exp: class:TestGitOperationsStatus, method:test_status_clean(self, temp_workspace: Workspace), call:GitOperations, call:asyncio.run, call:git.status, method:test_status_modified(self, temp_workspace: Workspace), call:open, call:os.path.join, call:f.write, call:GitOperations, call:asyncio.run, call:git.status, method:test_status_untracked(self, temp_workspace: Workspace), call:open, call:os.path.join, call:f.write, call:GitOperations, call:asyncio.run, call:git.status, class:TestGitOperationsCommit, method:test_commit_stages_and_commits(self, temp_workspace: Workspace), call:open, call:os.path.join, call:f.write, call:GitOperations, call:asyncio.run, call:git.commit, call:git.status, call:git.history, method:test_commit_fails_without_changes(self, temp_workspace: Workspace), call:GitOperations, call:pytest.raises, call:asyncio.run, call:git.commit, class:TestGitOperationsHistory, method:test_history_returns_commits(self, temp_workspace: Workspace), call:GitOperations, call:asyncio.run, call:git.history, call:len, method:test_history_filters_by_path(self, temp_workspace: Workspace), call:open, call:os.path.join, call:f.write, call:GitOperations, call:asyncio.run, call:git.commit, call:git.history, call:len, class:TestGitOperationsBranches, method:test_branches_lists_main(self, temp_workspace: Workspace), call:GitOperations, call:asyncio.run, call:git.branches, method:test_checkout_switches_branch(self, temp_workspace: Workspace), call:_run_git, call:GitOperations, call:asyncio.run, call:git.checkout, call:git.status, func:_run_git(*args: str, cwd: str) → None, call:subprocess.run, func:temp_workspace(), call:tempfile.TemporaryDirectory, call:_run_git, call:os.path.join, call:open, call:f.write, call:Workspace | dep: asyncio, os, subprocess, tempfile, pytest, src.models, src.services.git.git_operations, src.models.Workspace, src.services.git.git_operations.GitOperations
- test_git_repository_clone_preflight.py | Unit tests for git repository clone URL building and preflight accessibility checks | exp: func:test_build_provider_clone_url_uses_fixed_host() → None, call:_build_provider_clone_url, func:test_preflight_remote_repository_allows_accessible_repo() → None, call:Mock, call:patch, call:_preflight_remote_repository, call:run_mock.assert_called_once, func:test_preflight_remote_repository_rejects_missing_repo() → None, call:Mock, call:patch, call:pytest.raises, call:_preflight_remote_repository | dep: unittest.mock, pytest, fastapi, src.api.git_repositories, subprocess
- test_git_repository_working_clones.py | Tests git repository cloning and initialization utilities with fallback strategies for different git versions | exp: func:test_clone_working_repository_uses_normal_clone() → None, call:Mock, call:patch, call:_clone_working_repository, call:run_mock.assert_called_once, func:test_clone_working_repository_raises_on_failure() → None, call:Mock, call:patch, call:pytest.raises, call:_clone_working_repository, func:test_init_working_repository_prefers_init_b() → None, call:Mock, call:patch, call:_init_working_repository, func:test_init_working_repository_falls_back_to_symbolic_ref() → None, call:Mock, call:patch, call:_init_working_repository, func:test_create_branch_uses_orphan_checkout_when_head_is_unborn() → None, call:patch, call:create_branch, raise:RuntimeError, func:mock_run(repo_path: str, *args: str) → str, raise:RuntimeError | dep: unittest.mock, pytest, fastapi, src.api.git_repositories, src.utils.git_control, subprocess
- test_git_service.py | Unit tests for GitService class covering clone, fetch, pull, and branch_exists_remotely operations with mocked subprocess calls. | exp: class:TestGitServiceClone, class:TestGitServiceFetch, class:TestGitServicePull, class:TestGitServiceBranchExistsRemotely, method:test_branch_exists(self), call:MagicMock, call:patch, call:GitService.branch_exists_remotely, call:mock_run.assert_called_once_with, method:test_branch_not_exists(self), call:MagicMock, call:patch, call:GitService.branch_exists_remotely, method:test_ls_remote_fails(self), call:MagicMock, call:patch, call:GitService.branch_exists_remotely | dep: asyncio, unittest.mock, pytest, src.services.git_service
- test_config.py | Tests configuration settings and database URL building for an application, verifying defaults, environment variable overrides, and environment-specific behavior. | exp: func:test_settings_default_database_url_uses_asyncpg(monkeypatch) → None, call:monkeypatch.delenv, call:Settings, func:test_build_database_url_uses_explicit_values() → None, call:build_database_url, func:test_settings_prefers_explicit_database_url_env(monkeypatch) → None, call:monkeypatch.setenv, call:Settings, func:test_auth_settings_have_secure_defaults() → None, call:Settings, call:settings.resolved_authentik_authorize_url.endswith, call:settings.resolved_authentik_token_url.endswith, call:settings.resolved_authentik_jwks_url.endswith, func:test_cookie_policy_is_strict_in_production(monkeypatch) → None, call:monkeypatch.setenv, call:Settings, func:test_cookie_policy_is_relaxed_for_local_dev(monkeypatch) → None, call:monkeypatch.setenv, call:Settings | dep: pytest, src.config, src.database
- test_config_profile_resolver.py | Unit tests for config profile resolution including merge functions, profile inheritance with includes, cycle detection, and git mount normalization | exp: class:TestMergeFunctions, method:test_merge_env_vars_basic(self) → None, call:_merge_env_vars, method:test_merge_env_vars_tracks_overrides(self) → None, call:_merge_env_vars, method:test_merge_runtime_hints_basic(self) → None, call:_merge_runtime_hints, method:test_merge_files_basic(self) → None, call:_merge_files, method:test_merge_mounts_basic(self) → None, call:_merge_mounts, method:test_merge_mounts_file_override(self) → None, call:_merge_mounts, call:ResolvedMount, method:test_merge_mounts_mode_conflict(self) → None, call:_merge_mounts, call:ResolvedMount, method:test_merge_git_mounts_basic(self) → None, call:_merge_git_mounts, call:len, method:test_merge_git_mounts_concatenate_same_repo_branch(self) → None, call:_merge_git_mounts, call:len, method:test_merge_git_mounts_dedup_same_mapping(self) → None, call:_merge_git_mounts, call:len, method:test_merge_git_mounts_different_repos(self) → None, call:_merge_git_mounts, call:len, method:test_merge_git_mounts_different_branches(self) → None, call:_merge_git_mounts, call:len, call:m.get, class:TestResolveProfile, class:TestApplyResolvedProfile, method:test_mounts_individual_files_not_directory(self, tmp_path) → None, call:ResolvedProfile, call:uuid.uuid4, call:ResolvedMount, call:apply_resolved_profile, call:str, call:len, method:test_file_mount_preserves_sibling_files(self, tmp_path) → None, call:ResolvedProfile, call:uuid.uuid4, call:ResolvedMount, call:apply_resolved_profile, call:str, call:len, call:volumes[0]["source"].endswith, method:test_empty_mount_produces_no_volumes(self, tmp_path) → None, call:ResolvedProfile, call:uuid.uuid4, call:ResolvedMount, call:apply_resolved_profile, call:str, method:test_home_expansion_in_file_mount_target(self, tmp_path) → None, call:ResolvedProfile, call:uuid.uuid4, call:ResolvedMount, call:apply_resolved_profile, call:str, class:TestCheckIncludeCycle | dep: uuid, pytest, sqlalchemy.ext.asyncio, src.models.config.config_profile, src.services.config.config_profile_resolver
- test_docker_build.py | Unit tests for a Docker image build service that verifies Dockerfile creation, command structure, context file handling, path traversal prevention, and error handling. | exp: class:TestBuildImage | dep: subprocess, tempfile, pathlib, unittest.mock, pytest, src.services.build.docker_build
- test_docker_service.py | Unit tests for Docker service utilities including container ID/name retrieval and volume sorting by specificity. | exp: class:TestGetContainerId, class:TestGetContainerName, class:TestSortVolumesBySpecificity, method:test_parent_before_child(self) → None, call:sort_volumes_by_specificity, method:test_stable_sort_for_equal_depth(self) → None, call:sort_volumes_by_specificity, method:test_with_type_suffix(self) → None, call:sort_volumes_by_specificity, method:test_empty_list(self) → None, call:sort_volumes_by_specificity, method:test_single_volume(self) → None, call:sort_volumes_by_specificity, method:test_duplicate_target_warning(self, caplog) → None, call:caplog.at_level, call:sort_volumes_by_specificity | dep: unittest.mock, logging, src.services.docker.container, src.services.docker.compose, subprocess
- test_event_bus.py | Unit tests for InstanceEventBus verifying publish/subscribe, exception isolation, unsubscribe, and async callback support. | exp: func:event_bus() → InstanceEventBus, call:InstanceEventBus, call:bus._reset_for_testing, func:sample_payload() → InstanceEventPayload, call:str, call:uuid.uuid4, func:test_publish_delivers_to_all_subscribers(event_bus: InstanceEventBus, sample_payload: InstanceEventPayload) → None, call:received.append, call:event_bus.subscribe, call:event_bus.publish, call:len, func:callback_1(payload: InstanceEventPayload) → None, call:received.append, func:callback_2(payload: InstanceEventPayload) → None, call:received.append, func:callback_3(payload: InstanceEventPayload) → None, call:received.append, func:test_subscriber_exception_isolation(event_bus: InstanceEventBus, sample_payload: InstanceEventPayload) → None, call:received.append, call:event_bus.subscribe, call:event_bus.publish, raise:RuntimeError, func:bad_callback(_payload: InstanceEventPayload) → None, raise:RuntimeError, func:good_callback(_payload: InstanceEventPayload) → None, call:received.append, func:test_unsubscribe_removes_callback(event_bus: InstanceEventBus, sample_payload: InstanceEventPayload) → None, call:received.append, call:event_bus.subscribe, call:unsubscribe, call:event_bus.publish, func:callback(_payload: InstanceEventPayload) → None, call:received.append, func:test_publish_to_empty_subscriber_list(event_bus: InstanceEventBus, sample_payload: InstanceEventPayload) → None, call:event_bus.publish, func:test_async_subscriber_supported(event_bus: InstanceEventBus, sample_payload: InstanceEventPayload) → None, call:asyncio.sleep, call:received.append, call:event_bus.subscribe, call:event_bus.publish, func:async_callback(_payload: InstanceEventPayload) → None, call:asyncio.sleep, call:received.append, func:test_unsubscribe_all_clears_subscribers(event_bus: InstanceEventBus, sample_payload: InstanceEventPayload) → None, call:received.append, call:event_bus.subscribe, call:event_bus.unsubscribe_all, call:event_bus.publish, func:callback(_payload: InstanceEventPayload) → None, call:received.append | dep: asyncio, uuid, typing, pytest, src.services.instance.event_bus
- test_file_service.py | Unit tests for FileService validating directory listing, file read/write, binary rejection, path traversal prevention, and workspace-based file operations. | exp: class:TestFileService, method:test_list_directory_empty(self, temp_workspace: Workspace), call:FileService, call:service.list_directory, method:test_list_directory_with_files(self, temp_workspace: Workspace), call:os.makedirs, call:os.path.join, call:open, call:f.write, call:FileService, call:service.list_directory, call:len, method:test_read_file(self, temp_workspace: Workspace), call:open, call:os.path.join, call:f.write, call:FileService, call:service.read_file, method:test_read_binary_file_rejected(self, temp_workspace: Workspace), call:open, call:os.path.join, call:f.write, call:FileService, call:pytest.raises, call:service.read_file, method:test_write_file(self, temp_workspace: Workspace), call:FileService, call:service.write_file, call:os.path.exists, call:os.path.join, call:open, call:f.read, method:test_path_escapes_workspace(self, temp_workspace: Workspace), call:FileService, call:pytest.raises, call:service.list_directory, func:temp_workspace(), call:tempfile.TemporaryDirectory, call:Workspace | dep: os, tempfile, pytest, src.models, src.services.shared.file_service, src.models.Workspace, src.services.shared.file_service.FileService
- test_git_operations.py | Unit tests for GitOperations class covering status, commit, history, and branch operations | exp: class:TestGitOperationsStatus, method:test_status_clean(self, temp_workspace: Workspace), call:GitOperations, call:asyncio.run, call:git.status, method:test_status_modified(self, temp_workspace: Workspace), call:open, call:os.path.join, call:f.write, call:GitOperations, call:asyncio.run, call:git.status, method:test_status_untracked(self, temp_workspace: Workspace), call:open, call:os.path.join, call:f.write, call:GitOperations, call:asyncio.run, call:git.status, class:TestGitOperationsCommit, method:test_commit_stages_and_commits(self, temp_workspace: Workspace), call:open, call:os.path.join, call:f.write, call:GitOperations, call:asyncio.run, call:git.commit, call:git.status, call:git.history, method:test_commit_fails_without_changes(self, temp_workspace: Workspace), call:GitOperations, call:pytest.raises, call:asyncio.run, call:git.commit, class:TestGitOperationsHistory, method:test_history_returns_commits(self, temp_workspace: Workspace), call:GitOperations, call:asyncio.run, call:git.history, call:len, method:test_history_filters_by_path(self, temp_workspace: Workspace), call:open, call:os.path.join, call:f.write, call:GitOperations, call:asyncio.run, call:git.commit, call:git.history, call:len, class:TestGitOperationsBranches, method:test_branches_lists_main(self, temp_workspace: Workspace), call:GitOperations, call:asyncio.run, call:git.branches, method:test_checkout_switches_branch(self, temp_workspace: Workspace), call:_run_git, call:GitOperations, call:asyncio.run, call:git.checkout, call:git.status, func:_run_git(*args: str, cwd: str) → None, call:subprocess.run, func:temp_workspace(), call:tempfile.TemporaryDirectory, call:_run_git, call:os.path.join, call:open, call:f.write, call:Workspace | dep: asyncio, os, subprocess, tempfile, pytest, src.models, src.services.git.git_operations, src.models.Workspace, src.services.git.git_operations.GitOperations
- test_git_service.py | Unit tests for GitService class covering clone, fetch, pull, and branch_exists_remotely operations with mocked subprocess calls. | exp: class:TestGitServiceClone, class:TestGitServiceFetch, class:TestGitServicePull, class:TestGitServiceBranchExistsRemotely, method:test_branch_exists(self), call:MagicMock, call:patch, call:GitService.branch_exists_remotely, call:mock_run.assert_called_once_with, method:test_branch_not_exists(self), call:MagicMock, call:patch, call:GitService.branch_exists_remotely, method:test_ls_remote_fails(self), call:MagicMock, call:patch, call:GitService.branch_exists_remotely | dep: asyncio, unittest.mock, pytest, src.services.git.git_service
- test_git_url_parser.py | Tests for git URL parsing utilities that extract base repository URLs, validate clone URLs, and parse various git URL formats across GitHub, GitLab, and Bitbucket. | exp: class:TestExtractBaseRepoUrl, method:test_github_tree_url(self), call:extract_base_repo_url, method:test_github_blob_url(self), call:extract_base_repo_url, method:test_github_pull_url(self), call:extract_base_repo_url, method:test_github_issues_url(self), call:extract_base_repo_url, method:test_github_valid_url(self), call:extract_base_repo_url, method:test_github_url_with_query_params(self), call:extract_base_repo_url, method:test_gitlab_tree_url(self), call:extract_base_repo_url, method:test_gitlab_blob_url(self), call:extract_base_repo_url, method:test_gitlab_merge_request_url(self), call:extract_base_repo_url, method:test_gitlab_valid_url(self), call:extract_base_repo_url, method:test_bitbucket_src_url(self), call:extract_base_repo_url, method:test_bitbucket_valid_url(self), call:extract_base_repo_url, method:test_ssh_url(self), call:extract_base_repo_url, method:test_ssh_url_without_git_suffix(self), call:extract_base_repo_url, method:test_invalid_url(self), call:extract_base_repo_url, method:test_empty_url(self), call:extract_base_repo_url, class:TestIsValidCloneUrl, method:test_valid_ssh_url(self), call:is_valid_clone_url, method:test_valid_https_url(self), call:is_valid_clone_url, method:test_browser_url(self), call:is_valid_clone_url, method:test_url_without_git_suffix(self), call:is_valid_clone_url, method:test_invalid_url(self), call:is_valid_clone_url, class:TestParseGitUrl, method:test_valid_git_url(self), call:parse_git_url, method:test_browser_url(self), call:parse_git_url, method:test_invalid_url(self), call:parse_git_url, method:test_empty_url(self), call:parse_git_url, method:test_ssh_url(self), call:parse_git_url | dep: src.utils.git_url_parser, pytest
- test_health_monitor.py | Unit tests for HealthMonitor's state-transition logic covering container crashes, tunnel failures, recovery detection, deduplication, exception resilience, and lifecycle management. | exp: func:event_bus() → InstanceEventBus, call:InstanceEventBus, call:bus._reset_for_testing, func:health_monitor(event_bus: InstanceEventBus) → HealthMonitor, call:HealthMonitor, func:_create_running_instance(db_session) → ToolInstance, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, call:ToolInstance, func:test_detects_container_crash(db_session, event_bus: InstanceEventBus, health_monitor: HealthMonitor) → None, call:_create_running_instance, call:events_captured.append, call:event_bus.subscribe, call:patch, call:health_monitor._check_instance, call:db_session.refresh, call:len, call:db_session.execute, call:select(HealthCheck).where, call:result.scalar_one, func:capture_event(payload: InstanceEventPayload) → None, call:events_captured.append, func:test_detects_tunnel_failure(db_session, event_bus: InstanceEventBus, health_monitor: HealthMonitor) → None, call:_create_running_instance, call:events_captured.append, call:event_bus.subscribe, call:patch, call:health_monitor._check_instance, call:db_session.refresh, call:len, call:db_session.execute, call:select(HealthCheck).where, call:result.scalar_one, func:capture_event(payload: InstanceEventPayload) → None, call:events_captured.append, func:test_detects_recovery(db_session, event_bus: InstanceEventBus, health_monitor: HealthMonitor) → None, call:_create_running_instance, call:db_session.commit, call:HealthSnapshot, call:events_captured.append, call:event_bus.subscribe, call:patch, call:health_monitor._check_instance, call:db_session.refresh, call:len, call:db_session.execute, call:select(HealthCheck).where, call:result.scalar_one, func:capture_event(payload: InstanceEventPayload) → None, call:events_captured.append, func:test_skips_writes_when_no_state_change(db_session, event_bus: InstanceEventBus, health_monitor: HealthMonitor) → None, call:_create_running_instance, call:patch, call:health_monitor._check_instance, call:db_session.execute, call:select(HealthCheck).where, call:len, call:result.scalars().all, func:test_docker_exception_resilience(db_session, event_bus: InstanceEventBus, health_monitor: HealthMonitor) → None, call:_create_running_instance, call:events_captured.append, call:event_bus.subscribe, call:patch, call:RuntimeError, call:health_monitor._check_instance, call:db_session.execute, call:select(HealthCheck).where, call:result.scalar_one_or_none, func:capture_event(payload: InstanceEventPayload) → None, call:events_captured.append, func:test_monitor_start_stop(health_monitor: HealthMonitor) → None, call:health_monitor.start, call:task.done, call:health_monitor.stop, call:suppress, call:task.cancelled | dep: asyncio, uuid, contextlib, unittest.mock, pytest, sqlalchemy, src.models.health_check, src.models.tool_instance, src.models.user, src.services.event_bus, src.services.health_monitor
- test_home_path_expansion.py | Unit tests for tilde and $HOME expansion in container paths across three helper functions. | exp: class:TestExpandContainerPath, method:test_tilde_slash_expands(self) → None, call:expand_container_path, method:test_tilde_alone_expands(self) → None, call:expand_container_path, method:test_dollar_home_slash_expands(self) → None, call:expand_container_path, method:test_dollar_home_alone_expands(self) → None, call:expand_container_path, method:test_absolute_path_unchanged(self) → None, call:expand_container_path, method:test_relative_path_unchanged(self) → None, call:expand_container_path, method:test_tilde_in_middle_unchanged(self) → None, call:expand_container_path, method:test_dollar_home_in_middle_unchanged(self) → None, call:expand_container_path, method:test_root_home(self) → None, call:expand_container_path, class:TestGetManifestHomeDir, method:test_with_user_block(self) → None, call:get_manifest_home_dir, method:test_without_user_block(self) → None, call:get_manifest_home_dir, method:test_with_empty_user_name(self) → None, call:get_manifest_home_dir, method:test_with_none_user_name(self) → None, call:get_manifest_home_dir, class:TestResolveGitMountMappingsExpansion, method:test_tilde_target_expansion(self, tmp_path) → None, call:(tmp_path / "src").mkdir, call:_resolve_git_mount_mappings, call:str, call:len, method:test_dollar_home_target_expansion(self, tmp_path) → None, call:(tmp_path / "src").mkdir, call:_resolve_git_mount_mappings, call:str, call:len, method:test_absolute_target_unchanged(self, tmp_path) → None, call:(tmp_path / "src").mkdir, call:_resolve_git_mount_mappings, call:str, call:len | dep: pytest, src.api.tool_instances, src.services.config_profile_resolver, src.services.manifest_compiler
- test_lifecycle_hooks.py | Unit tests for lifecycle hook helper functions that derive notification titles and determine whether events should trigger notifications based on event type and status. | exp: class:TestDeriveTitle, method:test_known_event_types(self) → None, call:_derive_title, method:test_unknown_event_type(self) → None, call:_derive_title, class:TestShouldNotify, method:test_error_events_are_notified(self) → None, call:_should_notify, method:test_health_changed_running_is_notified(self) → None, call:_should_notify, method:test_created_started_stopped_restarted_deleted_filtered(self) → None, call:_should_notify, method:test_health_changed_non_running_filtered(self) → None, call:_should_notify | dep: pytest, src.services.lifecycle_hooks
- test_health_monitor.py | Unit tests for HealthMonitor state-transition logic covering container crash detection, tunnel failure detection, recovery detection, write deduplication, exception resilience, and start/stop lifecycle. | exp: func:event_bus() → InstanceEventBus, call:InstanceEventBus, call:bus._reset_for_testing, func:health_monitor(event_bus: InstanceEventBus) → HealthMonitor, call:HealthMonitor, func:_create_running_instance(db_session) → ToolInstance, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, call:ToolInstance, func:test_detects_container_crash(db_session, event_bus: InstanceEventBus, health_monitor: HealthMonitor) → None, call:_create_running_instance, call:events_captured.append, call:event_bus.subscribe, call:patch, call:health_monitor._check_instance, call:db_session.refresh, call:len, call:db_session.execute, call:select(HealthCheck).where, call:result.scalar_one, func:capture_event(payload: InstanceEventPayload) → None, call:events_captured.append, func:test_detects_tunnel_failure(db_session, event_bus: InstanceEventBus, health_monitor: HealthMonitor) → None, call:_create_running_instance, call:events_captured.append, call:event_bus.subscribe, call:patch, call:health_monitor._check_instance, call:db_session.refresh, call:len, call:db_session.execute, call:select(HealthCheck).where, call:result.scalar_one, func:capture_event(payload: InstanceEventPayload) → None, call:events_captured.append, func:test_detects_recovery(db_session, event_bus: InstanceEventBus, health_monitor: HealthMonitor) → None, call:_create_running_instance, call:db_session.commit, call:HealthSnapshot, call:events_captured.append, call:event_bus.subscribe, call:patch, call:health_monitor._check_instance, call:db_session.refresh, call:len, call:db_session.execute, call:select(HealthCheck).where, call:result.scalar_one, func:capture_event(payload: InstanceEventPayload) → None, call:events_captured.append, func:test_skips_writes_when_no_state_change(db_session, event_bus: InstanceEventBus, health_monitor: HealthMonitor) → None, call:_create_running_instance, call:HealthSnapshot, call:patch, call:health_monitor._check_instance, call:db_session.execute, call:select(HealthCheck).where, call:len, call:result.scalars().all, func:test_docker_exception_resilience(db_session, event_bus: InstanceEventBus, health_monitor: HealthMonitor) → None, call:_create_running_instance, call:events_captured.append, call:event_bus.subscribe, call:patch, call:RuntimeError, call:health_monitor._check_instance, call:db_session.execute, call:select(HealthCheck).where, call:result.scalar_one_or_none, func:capture_event(payload: InstanceEventPayload) → None, call:events_captured.append, func:test_monitor_start_stop(health_monitor: HealthMonitor) → None, call:health_monitor.start, call:task.done, call:health_monitor.stop, call:suppress, call:task.cancelled | dep: asyncio, uuid, contextlib, unittest.mock, pytest, sqlalchemy, src.models.system.health_check, src.models.tool.tool_instance, src.models.user.user, src.services.instance.event_bus, src.services.instance.health_monitor
- test_home_path_expansion.py | Unit tests for home directory path expansion (~ and $HOME) in container paths and manifest home directory resolution. | exp: class:TestExpandContainerPath, method:test_tilde_slash_expands(self) → None, call:expand_container_path, method:test_tilde_alone_expands(self) → None, call:expand_container_path, method:test_dollar_home_slash_expands(self) → None, call:expand_container_path, method:test_dollar_home_alone_expands(self) → None, call:expand_container_path, method:test_absolute_path_unchanged(self) → None, call:expand_container_path, method:test_relative_path_unchanged(self) → None, call:expand_container_path, method:test_tilde_in_middle_unchanged(self) → None, call:expand_container_path, method:test_dollar_home_in_middle_unchanged(self) → None, call:expand_container_path, method:test_root_home(self) → None, call:expand_container_path, class:TestGetManifestHomeDir, method:test_with_user_block(self) → None, call:get_manifest_home_dir, method:test_without_user_block(self) → None, call:get_manifest_home_dir, method:test_with_empty_user_name(self) → None, call:get_manifest_home_dir, method:test_with_none_user_name(self) → None, call:get_manifest_home_dir | dep: pytest, src.services.config.config_profile_resolver, src.services.build.manifest_compiler
- test_lifecycle_hooks.py | Unit tests for lifecycle hook helper functions that derive notification titles and determine whether events should trigger notifications. | exp: class:TestDeriveTitle, method:test_known_event_types(self) → None, call:_derive_title, method:test_unknown_event_type(self) → None, call:_derive_title, class:TestShouldNotify, method:test_error_events_are_notified(self) → None, call:_should_notify, method:test_health_changed_running_is_notified(self) → None, call:_should_notify, method:test_created_started_stopped_restarted_deleted_filtered(self) → None, call:_should_notify, method:test_health_changed_non_running_filtered(self) → None, call:_should_notify | dep: pytest, src.services.instance.lifecycle_hooks
- test_manifest_compiler.py | Unit tests for a manifest compiler that generates Dockerfiles with user configuration and home directory setup | exp: func:test_compile_dockerfile_creates_config_dirs_for_user() → None, call:compile_dockerfile, func:test_compile_dockerfile_no_user_does_not_create_home() → None, call:compile_dockerfile | dep: pytest, src.services.build.manifest_compiler
- test_migration_metadata.py | Tests Alembic database migration files for correct table definitions and revision chain metadata | exp: func:test_initial_migration_defines_all_core_tables() → None, call:Path(__file__).resolve, call:spec_from_file_location, call:module_from_spec, call:spec.loader.exec_module, func:test_refresh_tokens_migration_has_expected_revision_chain() → None, call:Path(__file__).resolve, call:spec_from_file_location, call:module_from_spec, call:spec.loader.exec_module | dep: pytest, importlib.util, pathlib, pathlib.Path
- test_monitoring_models.py | Unit tests for monitoring models (InstanceEvent, HealthCheck) and their database persistence/querying. | exp: func:test_instance_event_creation(db_session) → None, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, call:ToolInstance, call:InstanceEvent, call:db_session.refresh, call:isinstance, func:test_health_check_creation(db_session) → None, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, call:ToolInstance, call:HealthCheck, call:db_session.refresh, call:isinstance, func:test_instance_event_query_by_instance(db_session) → None, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, call:ToolInstance, call:InstanceEvent, call:db_session.execute, call:select(InstanceEvent).where, call:result.scalar_one | dep: uuid, datetime, pytest, sqlalchemy, src.models.health_check, src.models.instance_event, src.models.tool_instance, src.models.user
- test_notification_service.py | Unit tests for NotificationService covering CRUD operations, filtering, ownership validation, and bulk actions on user notifications. | exp: func:notification_service() → NotificationService, call:NotificationService, func:user_a(db_session: AsyncSession) → User, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, func:user_b(db_session: AsyncSession) → User, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, func:test_create_notification(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:uuid.uuid4, func:test_list_notifications_orders_by_created_at_desc(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:datetime.now, call:timedelta, call:db_session.commit, call:db_session.refresh, call:notification_service.list_notifications, func:test_list_notifications_excludes_dismissed(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:notification_service.dismiss, call:notification_service.list_notifications, func:test_list_notifications_unread_only(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:notification_service.mark_read, call:notification_service.list_notifications, func:test_get_unread_count(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:range, call:notification_service.create_notification, call:notification_service.mark_read, call:notification_service.get_unread_count, func:test_mark_read_sets_read_at(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:notification_service.mark_read, func:test_mark_all_read_affects_all_unread(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:range, call:notification_service.create_notification, call:notification_service.mark_all_read, call:notification_service.get_unread_count, func:test_dismiss_sets_dismissed_at(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:notification_service.dismiss, call:db_session.execute, call:select(Notification).where, call:result.scalar_one, func:test_mark_read_wrong_owner_raises(db_session: AsyncSession, notification_service: NotificationService, user_a: User, user_b: User) → None, call:notification_service.create_notification, call:pytest.raises, call:notification_service.mark_read, func:test_dismiss_wrong_owner_raises(db_session: AsyncSession, notification_service: NotificationService, user_a: User, user_b: User) → None, call:notification_service.create_notification, call:pytest.raises, call:notification_service.dismiss, func:test_list_notifications_mute_categories(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:notification_service.list_notifications, func:test_get_unread_count_excludes_dismissed(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:notification_service.dismiss, call:notification_service.get_unread_count, func:test_dismiss_all_affects_all_non_dismissed(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:range, call:notification_service.create_notification, call:notification_service.dismiss_all, call:notification_service.list_notifications, func:test_dismiss_all_affects_only_caller(db_session: AsyncSession, notification_service: NotificationService, user_a: User, user_b: User) → None, call:range, call:notification_service.create_notification, call:notification_service.dismiss_all, call:notification_service.list_notifications, func:test_mark_all_read_affects_only_caller(db_session: AsyncSession, notification_service: NotificationService, user_a: User, user_b: User) → None, call:range, call:notification_service.create_notification, call:notification_service.mark_all_read, call:notification_service.get_unread_count | dep: uuid, datetime, pytest, sqlalchemy, sqlalchemy.ext.asyncio, src.models.notification, src.models.user, src.services.notification_service
- test_notifications_api_routes.py | Tests that FastAPI notification routes are declared in correct order so bulk DELETE /notifications matches before parameterized DELETE /notifications/{id} | exp: func:test_delete_notifications_route_order() → None, call:FastAPI, call:app.include_router, call:TestClient, call:client.delete | dep: fastapi, fastapi.testclient, src.api.notifications
- test_permission_fixer.py | Unit tests for a Docker container permission fixer service that applies chown/chmod/file_mode to mounts and SSH directories. | exp: class:TestApplyMountPermissions, class:TestRunInContainer, class:TestApplySshPermissions, class:TestCheckRootUserAvailable | dep: unittest.mock, pytest, src.services.permission_fixer, subprocess
- test_readiness_probe.py | Unit tests for a Docker container readiness probe service that executes commands via docker exec with retry logic and timeout handling. | exp: class:TestExecuteProbe, class:TestIntegrationScenarios | dep: unittest.mock, src.services.readiness_probe, subprocess
- test_ssh_keys.py | Unit tests for SSH key preparation functionality that decrypts encrypted private keys and writes SSH key files with proper permissions and optional ownership. | exp: class:TestPrepareSshKeyFiles | dep: os, pathlib, unittest.mock, pytest, src.services.ssh_keys
- test_monitoring_models.py | Unit tests verifying creation, persistence, and querying of monitoring models (InstanceEvent and HealthCheck) with database migration compatibility. | exp: func:test_instance_event_creation(db_session) → None, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, call:ToolInstance, call:InstanceEvent, call:db_session.refresh, call:isinstance, func:test_health_check_creation(db_session) → None, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, call:ToolInstance, call:HealthCheck, call:db_session.refresh, call:isinstance, func:test_instance_event_query_by_instance(db_session) → None, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, call:ToolInstance, call:InstanceEvent, call:db_session.execute, call:select(InstanceEvent).where, call:result.scalar_one | dep: uuid, datetime, pytest, sqlalchemy, src.models.system.health_check, src.models.system.instance_event, src.models.tool.tool_instance, src.models.user.user
- test_notification_service.py | Unit tests for NotificationService covering CRUD operations, filtering, sorting, and ownership isolation. | exp: func:notification_service() → NotificationService, call:NotificationService, func:user_a(db_session: AsyncSession) → User, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, func:user_b(db_session: AsyncSession) → User, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, func:test_create_notification(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:uuid.uuid4, func:test_list_notifications_orders_by_created_at_desc(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:datetime.now, call:timedelta, call:db_session.commit, call:db_session.refresh, call:notification_service.list_notifications, func:test_list_notifications_excludes_dismissed(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:notification_service.dismiss, call:notification_service.list_notifications, func:test_list_notifications_unread_only(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:notification_service.mark_read, call:notification_service.list_notifications, func:test_get_unread_count(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:range, call:notification_service.create_notification, call:notification_service.mark_read, call:notification_service.get_unread_count, func:test_mark_read_sets_read_at(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:notification_service.mark_read, func:test_mark_all_read_affects_all_unread(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:range, call:notification_service.create_notification, call:notification_service.mark_all_read, call:notification_service.get_unread_count, func:test_dismiss_sets_dismissed_at(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:notification_service.dismiss, call:db_session.execute, call:select(Notification).where, call:result.scalar_one, func:test_mark_read_wrong_owner_raises(db_session: AsyncSession, notification_service: NotificationService, user_a: User, user_b: User) → None, call:notification_service.create_notification, call:pytest.raises, call:notification_service.mark_read, func:test_dismiss_wrong_owner_raises(db_session: AsyncSession, notification_service: NotificationService, user_a: User, user_b: User) → None, call:notification_service.create_notification, call:pytest.raises, call:notification_service.dismiss, func:test_list_notifications_mute_categories(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:notification_service.list_notifications, func:test_get_unread_count_excludes_dismissed(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:notification_service.dismiss, call:notification_service.get_unread_count, func:test_dismiss_all_affects_all_non_dismissed(db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:range, call:notification_service.create_notification, call:notification_service.dismiss_all, call:notification_service.list_notifications, func:test_dismiss_all_affects_only_caller(db_session: AsyncSession, notification_service: NotificationService, user_a: User, user_b: User) → None, call:range, call:notification_service.create_notification, call:notification_service.dismiss_all, call:notification_service.list_notifications, func:test_mark_all_read_affects_only_caller(db_session: AsyncSession, notification_service: NotificationService, user_a: User, user_b: User) → None, call:range, call:notification_service.create_notification, call:notification_service.mark_all_read, call:notification_service.get_unread_count | dep: uuid, datetime, pytest, sqlalchemy, sqlalchemy.ext.asyncio, src.models.system.notification, src.models.user.user, src.services.shared.notification_service, NotificationService, Notification, User, AsyncSession
- test_notifications_api_routes.py | Tests that FastAPI notification routes are declared in correct order so bulk DELETE doesn't get intercepted by parameterized route | exp: func:test_delete_notifications_route_order() → None, call:FastAPI, call:app.include_router, call:TestClient, call:client.delete | dep: fastapi, fastapi.testclient, src.api.system.notifications
- test_permission_fixer.py | Unit tests for a Docker container permission fixer that adjusts mount and SSH permissions via docker exec commands. | exp: class:TestApplyMountPermissions, class:TestRunInContainer, class:TestApplySshPermissions, class:TestCheckRootUserAvailable | dep: unittest.mock, pytest, src.services.shared.permission_fixer, subprocess
- test_readiness_probe.py | Unit tests for a Docker container readiness probe service that executes commands via docker exec with retry logic. | exp: class:TestExecuteProbe, class:TestIntegrationScenarios | dep: unittest.mock, src.services.shared.readiness_probe, subprocess
- test_ssh_keys.py | Unit tests for SSH key preparation functionality including file creation, permissions, ownership, and error handling | exp: class:TestPrepareSshKeyFiles | dep: os, pathlib, unittest.mock, pytest, src.services.shared.ssh_keys
## arch
pytest-based unit testing with heavy mocking of external dependencies (Docker, Git subprocesses, databases), organized by service/component under test, using parameterized tests and fixture-based setup for isolated component verification.
Standard Python unittest/pytest structure with heavy use of mocking for external dependencies (Docker, Git subprocess, database), testing business logic in isolation without integration requirements.
## tags
test, call:, url, git, call:notification, mount, call:len, call:db
test, url, call:notification, git, call:db, merge, call:, src
## symbols
- TestMergeFunctions
- TestResolveProfile
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/uploads
## role
Handles file upload processing, storage, and management for the API application.
Handles file upload processing, storage, and retrieval for the API application.
## parent
index: apps/api/.pi-map.index.md
map: apps/api/.pi-map.md
+2 -2
View File
@@ -4,10 +4,10 @@ dir: apps/api/uploads
index: apps/api/uploads/.pi-map.index.md
## role
Handles file upload processing, storage, and management for the API application.
Handles file upload processing, storage, and retrieval for the API application.
## files
## arch
Modular service-oriented architecture with dedicated modules for different upload types (avatars, documents, images), using NestJS controllers/services with S3/cloud storage integration, file validation, and database persistence for upload metadata.
Express.js middleware pattern with multipart form parsing, likely using Multer or similar for file handling, with storage abstraction for local/cloud backends.
## tags
-
## symbols
+1 -1
View File
@@ -2,7 +2,7 @@
dir: apps/api/uploads/avatars
## role
Storage directory for user avatar image files uploaded through the API.
Storage directory for user avatar image files uploaded through the API application.
## parent
index: apps/api/uploads/.pi-map.index.md
map: apps/api/uploads/.pi-map.md
+2 -2
View File
@@ -4,14 +4,14 @@ dir: apps/api/uploads/avatars
index: apps/api/uploads/avatars/.pi-map.index.md
## role
Storage directory for user avatar image files uploaded through the API.
Storage directory for user avatar image files uploaded through the API application.
## files
- 30d2810a-cb00-4065-8e5d-c7d32a0b55c9.png | Binary file
- b342b640-d3c1-488d-bdba-0e2890d6c363.png | Binary file
- da1c3121-20d7-400c-8c94-507a9d890810.png | Binary file
- ee9fdd89-0dcc-4f46-9ad8-01f4ff93720d.png | Binary file
## arch
Simple flat file storage using UUID-named PNG files with no subdirectory organization or metadata indexing.
Simple static file storage using UUID-named PNG files in a flat directory structure, serving as a persistent blob store without database indexing or subdirectory organization.
## tags
binary, 30d2810a, cb00, 4065, 8e5d, c7d32a0b55c9, b342b640, d3c1
## symbols