chore: track all project map and index files
Add generated .pi-map.md and .pi-map.index.md files across the repository so the project navigation maps are shared and versioned. These artifacts are maintained by project_map_init/patch/validate and must be kept in sync with source edits. Note: .cache/ remains ignored (added in previous commit).
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
# .claude (index)
|
||||
dir: .claude
|
||||
|
||||
## role
|
||||
Configuration and instruction files for the Claude AI assistant integration.
|
||||
## parent
|
||||
index: ./.pi-map.index.md
|
||||
map: ./.pi-map.md
|
||||
## children
|
||||
- .claude/skills
|
||||
index: .claude/skills/.pi-map.index.md
|
||||
map: .claude/skills/.pi-map.md
|
||||
## files
|
||||
## links
|
||||
index: .claude/.pi-map.index.md
|
||||
map: .claude/.pi-map.md
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,18 @@
|
||||
# .claude
|
||||
dir: .claude
|
||||
|
||||
index: .claude/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Configuration and instruction files for the Claude AI assistant integration.
|
||||
## files
|
||||
## arch
|
||||
Simple flat-file configuration storage with no complex architecture; contains prompt templates, system instructions, or context files used to guide Claude's behavior in this project.
|
||||
## tags
|
||||
-
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,20 @@
|
||||
# .claude/skills (index)
|
||||
dir: .claude/skills
|
||||
|
||||
## role
|
||||
Empty directory placeholder for future Claude Code skill definitions or custom AI-assisted workflows.
|
||||
## parent
|
||||
index: .claude/.pi-map.index.md
|
||||
map: .claude/.pi-map.md
|
||||
## children
|
||||
- .claude/skills/sift-backlog
|
||||
index: .claude/skills/sift-backlog/.pi-map.index.md
|
||||
map: .claude/skills/sift-backlog/.pi-map.md
|
||||
## files
|
||||
## links
|
||||
index: .claude/skills/.pi-map.index.md
|
||||
map: .claude/skills/.pi-map.md
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,18 @@
|
||||
# .claude/skills
|
||||
dir: .claude/skills
|
||||
|
||||
index: .claude/skills/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Empty directory placeholder for future Claude Code skill definitions or custom AI-assisted workflows.
|
||||
## files
|
||||
## arch
|
||||
None (no files present); likely intended for declarative skill modules using Claude's skill system pattern.
|
||||
## tags
|
||||
-
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,19 @@
|
||||
# .claude/skills/sift-backlog (index)
|
||||
dir: .claude/skills/sift-backlog
|
||||
|
||||
## role
|
||||
Defines a workflow skill for triaging, organizing, and activating backlog tasks into actionable plans using a custom CLI tool.
|
||||
## parent
|
||||
index: .claude/skills/.pi-map.index.md
|
||||
map: .claude/skills/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- SKILL.md
|
||||
## links
|
||||
index: .claude/skills/sift-backlog/.pi-map.index.md
|
||||
map: .claude/skills/sift-backlog/.pi-map.md
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,19 @@
|
||||
# .claude/skills/sift-backlog
|
||||
dir: .claude/skills/sift-backlog
|
||||
|
||||
index: .claude/skills/sift-backlog/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Defines a workflow skill for triaging, organizing, and activating backlog tasks into actionable plans using a custom CLI tool.
|
||||
## files
|
||||
- SKILL.md | Defines a workflow skill for triaging, organizing, and activating backlog tasks into actionable plans using a custom CLI tool. | dep: sf (custom CLI tool), task management system, plan management system
|
||||
## arch
|
||||
Skill-based workflow automation following a structured triage pipeline (scan → filter → prioritize → activate) with CLI tool integration for backlog management.
|
||||
## tags
|
||||
skill, defines, workflow, triaging, organizing, activating, backlog, tasks
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,23 @@
|
||||
# .opencode (index)
|
||||
dir: .opencode
|
||||
|
||||
## role
|
||||
Configuration directory for the OpenCode AI coding assistant tool
|
||||
## parent
|
||||
index: ./.pi-map.index.md
|
||||
map: ./.pi-map.md
|
||||
## children
|
||||
- .opencode/commands
|
||||
index: .opencode/commands/.pi-map.index.md
|
||||
map: .opencode/commands/.pi-map.md
|
||||
- .opencode/skills
|
||||
index: .opencode/skills/.pi-map.index.md
|
||||
map: .opencode/skills/.pi-map.md
|
||||
## files
|
||||
## links
|
||||
index: .opencode/.pi-map.index.md
|
||||
map: .opencode/.pi-map.md
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,18 @@
|
||||
# .opencode
|
||||
dir: .opencode
|
||||
|
||||
index: .opencode/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Configuration directory for the OpenCode AI coding assistant tool
|
||||
## files
|
||||
## arch
|
||||
Tool-specific configuration storage using standard dot-directory convention with likely JSON/YAML config files and optional workspace state/logs
|
||||
## tags
|
||||
-
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,22 @@
|
||||
# .opencode/commands (index)
|
||||
dir: .opencode/commands
|
||||
|
||||
## role
|
||||
Defines structured workflow commands and AI assistant stances for an experimental OpenSpec-based development system that guides changes through exploration, proposal, implementation, and archival phases.
|
||||
## parent
|
||||
index: .opencode/.pi-map.index.md
|
||||
map: .opencode/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- opsx-apply.md
|
||||
- opsx-archive.md
|
||||
- opsx-explore.md
|
||||
- opsx-propose.md
|
||||
## links
|
||||
index: .opencode/commands/.pi-map.index.md
|
||||
map: .opencode/commands/.pi-map.md
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,22 @@
|
||||
# .opencode/commands
|
||||
dir: .opencode/commands
|
||||
|
||||
index: .opencode/commands/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Defines structured workflow commands and AI assistant stances for an experimental OpenSpec-based development system that guides changes through exploration, proposal, implementation, and archival phases.
|
||||
## files
|
||||
- opsx-apply.md | Defines an experimental workflow skill for implementing tasks from an OpenSpec change through a structured, interactive process with CLI integration and progress tracking. | dep: openspec CLI, AskUserQuestion tool, filesystem (for reading context files)
|
||||
- opsx-archive.md | Defines a workflow for archiving completed changes in an experimental openspec-based development system | dep: openspec CLI, AskUserQuestion tool, Task tool, Skill tool, filesystem (mkdir, mv), JSON parsing
|
||||
- opsx-explore.md | Defines the "explore mode" stance for an AI assistant - a thinking/discovery mode for investigating problems and clarifying requirements without implementing code | dep: OpenSpec system
|
||||
- opsx-propose.md | Defines a workflow for proposing new changes in the openspec system by creating a change directory and generating all required artifacts (proposal.md, design.md, tasks.md) in dependency order | dep: openspec CLI, AskUserQuestion tool, TodoWrite tool, JSON parsing
|
||||
## arch
|
||||
Markdown-based declarative workflow definitions using a command pattern where each `.md` file specifies a distinct operational stance or phase (explore/propose/apply/archive) with embedded metadata, structured steps, and CLI integration points for progressive change lifecycle management.
|
||||
## tags
|
||||
opsx, defines, workflow, openspec, openspec cli, askuserquestion tool, explore, experimental
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,29 @@
|
||||
# .opencode/skills (index)
|
||||
dir: .opencode/skills
|
||||
|
||||
## role
|
||||
Contains reusable skill modules that provide specific capabilities or integrations for the OpenCode agent framework.
|
||||
## parent
|
||||
index: .opencode/.pi-map.index.md
|
||||
map: .opencode/.pi-map.md
|
||||
## children
|
||||
- .opencode/skills/openspec-apply-change
|
||||
index: .opencode/skills/openspec-apply-change/.pi-map.index.md
|
||||
map: .opencode/skills/openspec-apply-change/.pi-map.md
|
||||
- .opencode/skills/openspec-archive-change
|
||||
index: .opencode/skills/openspec-archive-change/.pi-map.index.md
|
||||
map: .opencode/skills/openspec-archive-change/.pi-map.md
|
||||
- .opencode/skills/openspec-explore
|
||||
index: .opencode/skills/openspec-explore/.pi-map.index.md
|
||||
map: .opencode/skills/openspec-explore/.pi-map.md
|
||||
- .opencode/skills/openspec-propose
|
||||
index: .opencode/skills/openspec-propose/.pi-map.index.md
|
||||
map: .opencode/skills/openspec-propose/.pi-map.md
|
||||
## files
|
||||
## links
|
||||
index: .opencode/skills/.pi-map.index.md
|
||||
map: .opencode/skills/.pi-map.md
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,18 @@
|
||||
# .opencode/skills
|
||||
dir: .opencode/skills
|
||||
|
||||
index: .opencode/skills/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Contains reusable skill modules that provide specific capabilities or integrations for the OpenCode agent framework.
|
||||
## files
|
||||
## arch
|
||||
Modular plugin-based architecture where each skill is a self-contained unit implementing standardized interfaces for dynamic discovery and loading by the agent core.
|
||||
## tags
|
||||
-
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,19 @@
|
||||
# .opencode/skills/openspec-apply-change (index)
|
||||
dir: .opencode/skills/openspec-apply-change
|
||||
|
||||
## role
|
||||
Provides a spec-driven AI skill that implements tasks from OpenSpec changes by applying structured modifications to a codebase.
|
||||
## parent
|
||||
index: .opencode/skills/.pi-map.index.md
|
||||
map: .opencode/skills/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- SKILL.md
|
||||
## links
|
||||
index: .opencode/skills/openspec-apply-change/.pi-map.index.md
|
||||
map: .opencode/skills/openspec-apply-change/.pi-map.md
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,19 @@
|
||||
# .opencode/skills/openspec-apply-change
|
||||
dir: .opencode/skills/openspec-apply-change
|
||||
|
||||
index: .opencode/skills/openspec-apply-change/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Provides a spec-driven AI skill that implements tasks from OpenSpec changes by applying structured modifications to a codebase.
|
||||
## files
|
||||
- SKILL.md | Defines an AI assistant skill for implementing tasks from an OpenSpec change using a spec-driven workflow | dep: openspec CLI, AskUserQuestion tool, filesystem access
|
||||
## arch
|
||||
Skill-based modular architecture using markdown-defined capabilities with a workflow-driven pattern that separates specification parsing from implementation execution.
|
||||
## tags
|
||||
skill, defines, assistant, implementing, tasks, openspec, change, spec
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,19 @@
|
||||
# .opencode/skills/openspec-archive-change (index)
|
||||
dir: .opencode/skills/openspec-archive-change
|
||||
|
||||
## role
|
||||
Provides a skill definition for archiving completed changes in an experimental workflow using the openspec CLI.
|
||||
## parent
|
||||
index: .opencode/skills/.pi-map.index.md
|
||||
map: .opencode/skills/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- SKILL.md
|
||||
## links
|
||||
index: .opencode/skills/openspec-archive-change/.pi-map.index.md
|
||||
map: .opencode/skills/openspec-archive-change/.pi-map.md
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,19 @@
|
||||
# .opencode/skills/openspec-archive-change
|
||||
dir: .opencode/skills/openspec-archive-change
|
||||
|
||||
index: .opencode/skills/openspec-archive-change/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Provides a skill definition for archiving completed changes in an experimental workflow using the openspec CLI.
|
||||
## files
|
||||
- SKILL.md | Defines a skill for archiving completed changes in an experimental workflow using the openspec CLI. | dep: openspec CLI, AskUserQuestion tool, Task tool, file system (mkdir, mv, read), JSON parsing
|
||||
## arch
|
||||
Single-file skill definition using markdown-based skill documentation pattern with CLI tool integration.
|
||||
## tags
|
||||
skill, defines, archiving, completed, changes, experimental, workflow, openspec
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,19 @@
|
||||
# .opencode/skills/openspec-explore (index)
|
||||
dir: .opencode/skills/openspec-explore
|
||||
|
||||
## role
|
||||
Defines a conversational AI skill that acts as a thinking partner for exploring ideas, investigating problems, and clarifying requirements without implementing code.
|
||||
## parent
|
||||
index: .opencode/skills/.pi-map.index.md
|
||||
map: .opencode/skills/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- SKILL.md
|
||||
## links
|
||||
index: .opencode/skills/openspec-explore/.pi-map.index.md
|
||||
map: .opencode/skills/openspec-explore/.pi-map.md
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,19 @@
|
||||
# .opencode/skills/openspec-explore
|
||||
dir: .opencode/skills/openspec-explore
|
||||
|
||||
index: .opencode/skills/openspec-explore/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Defines a conversational AI skill that acts as a thinking partner for exploring ideas, investigating problems, and clarifying requirements without implementing code.
|
||||
## files
|
||||
- SKILL.md | Defines a conversational AI skill/persona for "explore mode" - a thinking partner for exploring ideas, investigating problems, and clarifying requirements without implementing code. | dep: openspec CLI
|
||||
## arch
|
||||
Markdown-based skill definition using persona/role-prompting pattern with structured behavioral guidelines for non-implementation exploratory conversations.
|
||||
## tags
|
||||
skill, defines, conversational, persona, explore, mode, thinking, partner
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,19 @@
|
||||
# .opencode/skills/openspec-propose (index)
|
||||
dir: .opencode/skills/openspec-propose
|
||||
|
||||
## role
|
||||
Defines a structured workflow skill for proposing new changes using the openspec CLI, generating proposal, design, and task artifacts in dependency order.
|
||||
## parent
|
||||
index: .opencode/skills/.pi-map.index.md
|
||||
map: .opencode/skills/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- SKILL.md
|
||||
## links
|
||||
index: .opencode/skills/openspec-propose/.pi-map.index.md
|
||||
map: .opencode/skills/openspec-propose/.pi-map.md
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,19 @@
|
||||
# .opencode/skills/openspec-propose
|
||||
dir: .opencode/skills/openspec-propose
|
||||
|
||||
index: .opencode/skills/openspec-propose/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Defines a structured workflow skill for proposing new changes using the openspec CLI, generating proposal, design, and task artifacts in dependency order.
|
||||
## files
|
||||
- SKILL.md | Defines a structured workflow for proposing new changes using the openspec CLI, generating proposal, design, and task artifacts in dependency order. | dep: openspec CLI, AskUserQuestion tool, TodoWrite tool
|
||||
## arch
|
||||
Template-based skill definition using markdown documentation with structured workflow patterns for CLI-driven artifact generation and dependency-ordered execution.
|
||||
## tags
|
||||
skill, defines, structured, workflow, proposing, new, changes, openspec
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,79 @@
|
||||
# . (index)
|
||||
dir: .
|
||||
|
||||
## Project Map Protocol
|
||||
|
||||
1. Read this protocol and the root `.pi-map.index.md` first.
|
||||
2. Use `index:` / `map:` references to open relevant directory indexes and maps.
|
||||
3. Load indexes before rich maps during task-start navigation.
|
||||
4. Read the local rich map and actual source before editing.
|
||||
5. Treat non-empty `## dirty` sections in either artifact as stale.
|
||||
6. If source and generated artifacts disagree, trust source.
|
||||
7. If map and index disagree, trust neither blindly; verify from source and regenerate the pair.
|
||||
8. After editing source, run `project_map_patch` for each changed file.
|
||||
9. Before broad architectural claims or final handoff, run `project_map_validate` when freshness matters.
|
||||
|
||||
Trust boundary: index routes, map orients, source decides.
|
||||
|
||||
## role
|
||||
Infrastructure and deployment configuration package for a self-hosted project management platform with containerized services, SSO integration, and reverse proxy support.
|
||||
## parent
|
||||
-
|
||||
## children
|
||||
- .atl
|
||||
index: .atl/.pi-map.index.md
|
||||
map: .atl/.pi-map.md
|
||||
- .claude
|
||||
index: .claude/.pi-map.index.md
|
||||
map: .claude/.pi-map.md
|
||||
- .opencode
|
||||
index: .opencode/.pi-map.index.md
|
||||
map: .opencode/.pi-map.md
|
||||
- .pi
|
||||
index: .pi/.pi-map.index.md
|
||||
map: .pi/.pi-map.md
|
||||
- .sisyphus
|
||||
index: .sisyphus/.pi-map.index.md
|
||||
map: .sisyphus/.pi-map.md
|
||||
- .stoneforge
|
||||
index: .stoneforge/.pi-map.index.md
|
||||
map: .stoneforge/.pi-map.md
|
||||
- apps
|
||||
index: apps/.pi-map.index.md
|
||||
map: apps/.pi-map.md
|
||||
- docs
|
||||
index: docs/.pi-map.index.md
|
||||
map: docs/.pi-map.md
|
||||
- e2e
|
||||
index: e2e/.pi-map.index.md
|
||||
map: e2e/.pi-map.md
|
||||
- minerv3
|
||||
index: minerv3/.pi-map.index.md
|
||||
map: minerv3/.pi-map.md
|
||||
- openspec
|
||||
index: openspec/.pi-map.index.md
|
||||
map: openspec/.pi-map.md
|
||||
- scripts
|
||||
index: scripts/.pi-map.index.md
|
||||
map: scripts/.pi-map.md
|
||||
- tool-images
|
||||
index: tool-images/.pi-map.index.md
|
||||
map: tool-images/.pi-map.md
|
||||
## files
|
||||
- .env.example
|
||||
- .gitignore
|
||||
- AGENTS.md
|
||||
- CHANGELOG.md
|
||||
- Makefile
|
||||
- README.md
|
||||
- docker-compose.traefik.yml
|
||||
- docker-compose.yml
|
||||
- progress.md
|
||||
- swap-pane
|
||||
## links
|
||||
index: ./.pi-map.index.md
|
||||
map: ./.pi-map.md
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
# .
|
||||
dir: .
|
||||
|
||||
index: ./.pi-map.index.md
|
||||
|
||||
## Project Map Protocol
|
||||
|
||||
1. Read this protocol and the root `.pi-map.index.md` first.
|
||||
2. Use `index:` / `map:` references to open relevant directory indexes and maps.
|
||||
3. Load indexes before rich maps during task-start navigation.
|
||||
4. Read the local rich map and actual source before editing.
|
||||
5. Treat non-empty `## dirty` sections in either artifact as stale.
|
||||
6. If source and generated artifacts disagree, trust source.
|
||||
7. If map and index disagree, trust neither blindly; verify from source and regenerate the pair.
|
||||
8. After editing source, run `project_map_patch` for each changed file.
|
||||
9. Before broad architectural claims or final handoff, run `project_map_validate` when freshness matters.
|
||||
|
||||
Trust boundary: index routes, map orients, source decides.
|
||||
|
||||
## role
|
||||
Infrastructure and deployment configuration package for a self-hosted project management platform with containerized services, SSO integration, and reverse proxy support.
|
||||
## files
|
||||
- .env.example | Provides a template of environment variables for configuring a Headquarter application with PostgreSQL, Redis, Authentik SSO, and Docker/Traefik deployment
|
||||
- .gitignore | Specifies patterns for files and directories that Git should ignore in this repository | dep: git, none
|
||||
- AGENTS.md | Defines operational rules, workflows, and constraints for AI agents working within an OpenSpec-driven software development project. | dep: OpenSpec, superpowers, git, docker compose, conventional commits
|
||||
- CHANGELOG.md | Documents version history and notable changes for a Git-based project management web application
|
||||
- Makefile | Provides standard development commands for containerized web application lifecycle management via Docker Compose | dep: docker compose, alembic, pytest, ruff, mypy, playwright, npm, postgres, redis
|
||||
- README.md | A self-hosted platform for managing projects, git repositories, and development tools with OAuth2 authentication. | dep: FastAPI, SQLAlchemy, Pydantic, Alembic, python-jose, React, TypeScript, Vite, React Router, Docker, PostgreSQL, Traefik, Authentik, Git
|
||||
- docker-compose.traefik.yml | Deploys a multi-service web application (frontend, API, PostgreSQL, Redis) behind an existing Traefik reverse proxy with TLS termination and environment-configurable domains. | dep: docker, traefik, postgres, redis, authentik, docker-compose
|
||||
- docker-compose.yml | Defines a multi-service Docker Compose stack with PostgreSQL, Redis, API backend, and web frontend services for a "headquarter" application | dep: Docker, PostgreSQL, Redis, Vite, asyncpg, nginx
|
||||
- progress.md | Tracks completed and remaining tasks for a backend-frontend code refactoring project organized in 7 phases
|
||||
- swap-pane | Empty file with no functionality
|
||||
## arch
|
||||
Docker Compose-based microservices architecture with environment-driven configuration, Traefik reverse proxy integration, and separation of concerns between backend API, frontend, PostgreSQL persistence, and Redis caching layers.
|
||||
## tags
|
||||
docker, redis, git, application, postgresql, compose, traefik, web
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,23 @@
|
||||
# .stoneforge (index)
|
||||
dir: .stoneforge
|
||||
|
||||
## role
|
||||
Hidden system directory storing runtime state, configuration, and version-control metadata for the Stoneforge application.
|
||||
## parent
|
||||
index: ./.pi-map.index.md
|
||||
map: ./.pi-map.md
|
||||
## children
|
||||
- .stoneforge/sync
|
||||
index: .stoneforge/sync/.pi-map.index.md
|
||||
map: .stoneforge/sync/.pi-map.md
|
||||
## files
|
||||
- .dashboard-opened
|
||||
- .gitignore
|
||||
- config.yaml
|
||||
## links
|
||||
index: .stoneforge/.pi-map.index.md
|
||||
map: .stoneforge/.pi-map.md
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,21 @@
|
||||
# .stoneforge
|
||||
dir: .stoneforge
|
||||
|
||||
index: .stoneforge/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Hidden system directory storing runtime state, configuration, and version-control metadata for the Stoneforge application.
|
||||
## files
|
||||
- .dashboard-opened | Stores timestamp and identifier data for tracking when a dashboard was opened
|
||||
- .gitignore | Specifies files and patterns for Git to ignore in version control
|
||||
- config.yaml | Configuration file for the Stoneforge application defining database, sync, playbook, identity, merge, workflow, and agent settings.
|
||||
## arch
|
||||
Simple flat-file storage with YAML-based configuration, dotfile-based state tracking, and standard Git ignore patterns.
|
||||
## tags
|
||||
config, stores, timestamp, identifier, data, tracking, dashboard, was
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,20 @@
|
||||
# .stoneforge/sync (index)
|
||||
dir: .stoneforge/sync
|
||||
|
||||
## role
|
||||
Distributed task coordination and ephemeral worker agent management for a multi-agent execution system.
|
||||
## parent
|
||||
index: .stoneforge/.pi-map.index.md
|
||||
map: .stoneforge/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- dependencies.jsonl
|
||||
- elements.jsonl
|
||||
## links
|
||||
index: .stoneforge/sync/.pi-map.index.md
|
||||
map: .stoneforge/sync/.pi-map.md
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,20 @@
|
||||
# .stoneforge/sync
|
||||
dir: .stoneforge/sync
|
||||
|
||||
index: .stoneforge/sync/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Distributed task coordination and ephemeral worker agent management for a multi-agent execution system.
|
||||
## files
|
||||
- dependencies.jsonl | Stores a sequence of dependency relationships between entities in JSON Lines format, tracking parent-child, blocking, and reply relationships with timestamps and creators.
|
||||
- elements.jsonl | Stores JSONL records of ephemeral worker agents with their session history, worktree assignments, and lifecycle metadata for a distributed task execution system.
|
||||
## arch
|
||||
Event-sourced JSONL append-only logs with entity-relationship graph tracking, session-based worker lifecycle management, and decentralized worktree assignment.
|
||||
## tags
|
||||
stores, relationships, dependencies, elements, sequence, dependency, entities, json
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,23 @@
|
||||
# apps (index)
|
||||
dir: apps
|
||||
|
||||
## role
|
||||
Contains the main application entry points and executable modules for the project.
|
||||
## parent
|
||||
index: ./.pi-map.index.md
|
||||
map: ./.pi-map.md
|
||||
## children
|
||||
- apps/api
|
||||
index: apps/api/.pi-map.index.md
|
||||
map: apps/api/.pi-map.md
|
||||
- apps/web
|
||||
index: apps/web/.pi-map.index.md
|
||||
map: apps/web/.pi-map.md
|
||||
## files
|
||||
## links
|
||||
index: apps/.pi-map.index.md
|
||||
map: apps/.pi-map.md
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,18 @@
|
||||
# apps
|
||||
dir: apps
|
||||
|
||||
index: apps/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Contains the main application entry points and executable modules for the project.
|
||||
## files
|
||||
## arch
|
||||
Typically follows a modular architecture where each subdirectory represents a separate deployable application sharing common domain libraries.
|
||||
## tags
|
||||
-
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,39 @@
|
||||
# apps/api (index)
|
||||
dir: apps/api
|
||||
|
||||
## role
|
||||
Backend API server providing project management, git repository operations, and development tool orchestration via Docker containers.
|
||||
## parent
|
||||
index: apps/.pi-map.index.md
|
||||
map: apps/.pi-map.md
|
||||
## children
|
||||
- apps/api/.pi-lens
|
||||
index: apps/api/.pi-lens/.pi-map.index.md
|
||||
map: apps/api/.pi-lens/.pi-map.md
|
||||
- apps/api/alembic
|
||||
index: apps/api/alembic/.pi-map.index.md
|
||||
map: apps/api/alembic/.pi-map.md
|
||||
- apps/api/src
|
||||
index: apps/api/src/.pi-map.index.md
|
||||
map: apps/api/src/.pi-map.md
|
||||
- apps/api/tests
|
||||
index: apps/api/tests/.pi-map.index.md
|
||||
map: apps/api/tests/.pi-map.md
|
||||
- apps/api/uploads
|
||||
index: apps/api/uploads/.pi-map.index.md
|
||||
map: apps/api/uploads/.pi-map.md
|
||||
## files
|
||||
- .dockerignore
|
||||
- Dockerfile
|
||||
- README.md
|
||||
- alembic.ini
|
||||
- pyproject.toml
|
||||
- uv.lock
|
||||
- wait-for-db.sh
|
||||
## links
|
||||
index: apps/api/.pi-map.index.md
|
||||
map: apps/api/.pi-map.md
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,25 @@
|
||||
# apps/api
|
||||
dir: apps/api
|
||||
|
||||
index: apps/api/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Backend API server providing project management, git repository operations, and development tool orchestration via Docker containers.
|
||||
## 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
|
||||
- README.md | Documentation for a self-hosted FastAPI backend API that manages projects, git repositories, and development tools via Docker instances. | dep: FastAPI, SQLAlchemy, PostgreSQL, asyncpg, Alembic, Docker, Docker Compose, Authentik, uvicorn, pytest, ruff, mypy
|
||||
- alembic.ini | Configuration file for Alembic database migration tool connecting to a PostgreSQL database with async driver | dep: alembic, sqlalchemy, asyncpg, PostgreSQL
|
||||
- pyproject.toml | Defines Python project metadata, dependencies, and tool configurations for a FastAPI-based backend API called "headquarter-api" | dep: fastapi, uvicorn, sqlalchemy, asyncpg, alembic, pydantic, pydantic-settings, python-multipart, httpx, structlog, cryptography, pytest, pytest-asyncio, mypy, ruff, aiosqlite
|
||||
- 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
|
||||
FastAPI-based async Python service with multi-stage Docker deployment, PostgreSQL database with Alembic migrations, Cloudflare tunnel integration, and uv package management.
|
||||
## tags
|
||||
docker, alembic, python, database, fastapi, postgresql, asyncpg, uvicorn
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
-
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,25 @@
|
||||
# apps/api/alembic (index)
|
||||
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.
|
||||
## parent
|
||||
index: apps/api/.pi-map.index.md
|
||||
map: apps/api/.pi-map.md
|
||||
## children
|
||||
- apps/api/alembic/versions
|
||||
index: apps/api/alembic/versions/.pi-map.index.md
|
||||
map: apps/api/alembic/versions/.pi-map.md
|
||||
## files
|
||||
- env.py
|
||||
- script.py.mako
|
||||
## links
|
||||
index: apps/api/alembic/.pi-map.index.md
|
||||
map: apps/api/alembic/.pi-map.md
|
||||
## workflows
|
||||
- change alembic behavior
|
||||
read: env.py, script.py.mako
|
||||
- explore alembic subdirectories
|
||||
index: apps/api/alembic/versions/.pi-map.index.md
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,23 @@
|
||||
# apps/api/alembic
|
||||
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.
|
||||
## 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
|
||||
- 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.
|
||||
## tags
|
||||
sqlalchemy, alembic, database, migration, asyncio, config, src, env
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
- change alembic behavior
|
||||
read: env.py, script.py.mako
|
||||
- explore alembic subdirectories
|
||||
index: apps/api/alembic/versions/.pi-map.index.md
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,67 @@
|
||||
# apps/api/alembic/versions (index)
|
||||
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.
|
||||
## parent
|
||||
index: apps/api/alembic/.pi-map.index.md
|
||||
map: apps/api/alembic/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- 0001_initial_schema.py
|
||||
- 0002_refresh_tokens.py
|
||||
- 0003_user_configs.py
|
||||
- 0004_tool_types.py
|
||||
- 0005_ssh_keys_timestamps.py
|
||||
- 0006_tool_instances.py
|
||||
- 0007_instance_container_name.py
|
||||
- 0008_tool_type_category.py
|
||||
- 0009_tool_configs.py
|
||||
- 0010_tool_type_default_port.py
|
||||
- 0011_tool_instance_tunnel_fields.py
|
||||
- 0012_default_port_req.py
|
||||
- 0013_add_config_profiles.py
|
||||
- 0013_add_probe_result.py
|
||||
- 0014_add_profile_resolver_fields.py
|
||||
- 0014_merge_heads.py
|
||||
- 0015_single_interface.py
|
||||
- 069d3da4dc9b_add_ssh_key_id_to_config_profiles.py
|
||||
- 20260527160017_add_pi_agent_tool_type.py
|
||||
- 2026_05_22_add_clone_mode.py
|
||||
- 2026_05_23_remove_is_builtin.py
|
||||
- 2026_05_24_220141_add_startup_command.py
|
||||
- 2026_05_24_add_config_profiles.py
|
||||
- 2026_05_26_add_git_mounts.py
|
||||
- 2026_05_27_external_repos.py
|
||||
- 2026_05_28_add_monitoring_tables.py
|
||||
- 2026_05_28_add_terminal_sessions_table.py
|
||||
- 2026_05_28_add_tool_definition_manifests.py
|
||||
- 2026_05_28_drop_tool_configs_and_config_folders.py
|
||||
- 2026_05_29_add_notifications_table.py
|
||||
- 2026_05_29_add_ssh_key_ids_to_tool_instances.py
|
||||
- 2026_05_29_drop_ssh_key_id_from_config_profiles.py
|
||||
- 2026_05_29_fix_code_server_bind_addr.py
|
||||
- 2026_05_29_fix_code_server_bind_addr_port.py
|
||||
- 2026_05_29_fix_web_tool_bind_address.py
|
||||
- 2026_05_29_remove_lsio_command_override.py
|
||||
- 2026_05_29_remove_ssh_keys_mount_from_manifest.py
|
||||
- 2026_06_01_add_workspaces.py
|
||||
- 398082499c30_add_tool_config_fields.py
|
||||
- 6fc7bfcf199f_merge_remove_is_builtin_and_add_config_.py
|
||||
- 86cec91fdb00_merge_profile_resolver_and_workspaces_.py
|
||||
- 8ed7dd80973d_create_config_folders_table.py
|
||||
- af8512103d67_add_tool_type_fields.py
|
||||
- f3d2dc90ba3a_merge_single_interface_and_clone_mode.py
|
||||
## links
|
||||
index: apps/api/alembic/versions/.pi-map.index.md
|
||||
map: apps/api/alembic/versions/.pi-map.md
|
||||
## workflows
|
||||
- change versions behavior
|
||||
read: 0001_initial_schema.py, 0002_refresh_tokens.py, 0003_user_configs.py
|
||||
- change versions CLI
|
||||
read: 2026_05_24_220141_add_startup_command.py, 2026_05_29_remove_lsio_command_override.py
|
||||
- change versions config
|
||||
read: 0003_user_configs.py, 0009_tool_configs.py, 0013_add_config_profiles.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,74 @@
|
||||
# apps/api/alembic/versions
|
||||
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.
|
||||
## 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
|
||||
- 0003_user_configs.py | Alembic database migration that creates a user_configs table with JSON configuration storage linked to users | exp: func:upgrade() → None, call:op.create_table, call:sa.Column, call:sa.UUID, call:sa.JSON, call:sa.DateTime, call:sa.text, call:sa.ForeignKeyConstraint, call:sa.PrimaryKeyConstraint, call:sa.UniqueConstraint, func:downgrade() → None, call:op.drop_table | dep: typing, alembic, sqlalchemy
|
||||
- 0004_tool_types.py | Alembic database migration that creates a tool_types table with metadata, templates, and versioning columns for a tool management system. | exp: func:upgrade() → None, call:op.create_table, call:sa.Column, call:sa.Uuid, call:sa.String, call:sa.Text, call:sa.JSON, call:sa.Boolean, call:sa.ForeignKey, call:sa.DateTime, call:sa.text, func:downgrade() → None, call:op.drop_table | dep: typing, alembic, sqlalchemy
|
||||
- 0005_ssh_keys_timestamps.py | Alembic database migration that adds created_at and updated_at timestamp columns to the ssh_keys table | exp: func:upgrade() → None, call:op.add_column, call:sa.Column, call:sa.DateTime, call:sa.text, func:downgrade() → None, call:op.drop_column | dep: typing, alembic, sqlalchemy
|
||||
- 0006_tool_instances.py | Alembic database migration that creates a tool_instances table with columns for tracking deployed tool instances, their status, container info, and foreign key relationships to tool_types, git_repositories, projects, and users. | exp: func:upgrade() → None, call:op.create_table, call:sa.Column, call:postgresql.UUID, call:sa.text, call:sa.String, call:sa.Integer, call:sa.DateTime, call:sa.ForeignKeyConstraint, call:sa.PrimaryKeyConstraint, call:op.create_index, func:downgrade() → None, call:op.drop_index, call:op.drop_table | dep: typing, alembic, sqlalchemy.dialects, sqlalchemy, sqlalchemy.dialects.postgresql
|
||||
- 0007_instance_container_name.py | Alembic database migration that adds a nullable container_name column to the tool_instances table | exp: func:upgrade() → None, call:op.add_column, call:sa.Column, call:sa.String, func:downgrade() → None, call:op.drop_column | dep: typing, alembic, sqlalchemy
|
||||
- 0008_tool_type_category.py | Alembic database migration that adds `category` and `interfaces` columns to the `tool_types` table | exp: func:upgrade() → None, call:op.add_column, call:sa.Column, call:sa.String, call:sa.JSON, func:downgrade() → None, call:op.drop_column | dep: typing, alembic, sqlalchemy
|
||||
- 0009_tool_configs.py | Alembic database migration that creates a tool_configs table with UUID keys, foreign key relationships, and indexes for storing user/project tool configuration settings. | exp: func:upgrade() → None, call:op.create_table, call:sa.Column, call:postgresql.UUID, call:sa.text, call:sa.String, call:sa.Text, call:sa.DateTime, call:sa.ForeignKeyConstraint, call:sa.PrimaryKeyConstraint, call:op.create_index, func:downgrade() → None, call:op.drop_index, call:op.drop_table | dep: typing, alembic, sqlalchemy.dialects, sqlalchemy, postgresql dialect
|
||||
- 0010_tool_type_default_port.py | Alembic database migration that adds a nullable default_port column to the tool_types table. | exp: func:upgrade() → None, call:op.add_column, call:sa.Column, call:sa.Integer, func:downgrade() → None, call:op.drop_column | dep: typing, alembic, sqlalchemy
|
||||
- 0011_tool_instance_tunnel_fields.py | Alembic database migration that adds tunnel-related fields (public_url and tunnel_id) to the tool_instances table | exp: func:upgrade() → None, call:op.add_column, call:sa.Column, call:sa.String, func:downgrade() → None, call:op.drop_column | dep: typing, alembic, sqlalchemy
|
||||
- 0012_default_port_req.py | Alembic database migration that populates null default_port values for existing tool types and then makes the column non-nullable | exp: func:upgrade() → None, call:op.execute, call:op.alter_column, call:sa.Integer, func:downgrade() → None, call:op.alter_column, call:sa.Integer | dep: typing, alembic, sqlalchemy
|
||||
- 0013_add_config_profiles.py | Alembic database migration that adds config profiles, includes, mounts tables and links tool instances to profiles with defensive idempotent checks | exp: func:_table_exists(table_name: str) → bool, call:sa.inspect(op.get_bind()).has_table, call:op.get_bind, func:_column_exists(table_name: str, column_name: str) → bool, call:_table_exists, call:sa.inspect(op.get_bind()).get_columns, call:op.get_bind, func:_index_exists(table_name: str, index_name: str) → bool, call:_table_exists, call:sa.inspect(op.get_bind()).get_indexes, call:op.get_bind, func:_foreign_key_exists(table_name: str, constrained_columns: list[str], referred_table: str) → bool, call:_table_exists, call:sa.inspect(op.get_bind()).get_foreign_keys, call:op.get_bind, call:foreign_key.get, func:upgrade() → None, call:_table_exists, call:op.create_table, call:sa.Column, call:postgresql.UUID, call:sa.String, call:sa.Text, call:sa.DateTime, call:sa.text, call:sa.ForeignKeyConstraint, call:sa.PrimaryKeyConstraint, call:sa.UniqueConstraint, call:_index_exists, call:op.create_index, call:sa.Integer, call:_column_exists, call:op.add_column, call:_foreign_key_exists, call:op.create_foreign_key, func:downgrade() → None, call:op.drop_index, call:op.drop_constraint, call:op.drop_column, call:op.drop_table | dep: collections.abc, alembic, sqlalchemy.dialects, sqlalchemy, sqlalchemy.dialects.postgresql
|
||||
- 0013_add_probe_result.py | Alembic database migration that adds a JSON probe_result column to the tool_instances table | exp: func:upgrade() → None, call:op.add_column, call:sa.Column, func:downgrade() → None, call:op.drop_column | dep: typing, alembic, sqlalchemy.dialects, sqlalchemy, sqlalchemy.dialects.postgresql
|
||||
- 0014_add_profile_resolver_fields.py | Alembic database migration that adds profile resolver fields (project_id, tool_type_id, environment_variables, etc.) to config_profiles table and restructures config_mounts table (renaming mount_path to target_path, adding mode/files, removing content/source_profile_id). | exp: func:_table_exists(table_name: str) → bool, call:sa.inspect(op.get_bind()).has_table, call:op.get_bind, func:_column_exists(table_name: str, column_name: str) → bool, call:_table_exists, call:sa.inspect(op.get_bind()).get_columns, call:op.get_bind, func:_index_exists(table_name: str, index_name: str) → bool, call:_table_exists, call:sa.inspect(op.get_bind()).get_indexes, call:op.get_bind, func:_foreign_key_exists(table_name: str, constrained_columns: list[str], referred_table: str) → bool, call:_table_exists, call:sa.inspect(op.get_bind()).get_foreign_keys, call:op.get_bind, call:foreign_key.get, func:_foreign_key_names_for_column(table_name: str, column_name: str) → list[str], call:_table_exists, call:sa.inspect(op.get_bind()).get_foreign_keys, call:op.get_bind, call:foreign_key.get, call:names.append, func:upgrade() → None, call:_column_exists, call:op.add_column, call:sa.Column, call:postgresql.UUID, call:sa.JSON, call:sa.Text, call:sa.Integer, call:sa.Boolean, call:_foreign_key_exists, call:op.create_foreign_key, call:_index_exists, call:op.create_index, call:op.alter_column, call:sa.String, call:_foreign_key_names_for_column, call:op.drop_constraint, call:op.drop_column, func:downgrade() → None, call:op.add_column, call:sa.Column, call:postgresql.UUID, call:sa.Text, call:op.drop_column, call:op.alter_column, call:op.drop_index, call:op.drop_constraint | dep: collections.abc, alembic, sqlalchemy.dialects, sqlalchemy, sqlalchemy.dialects.postgresql
|
||||
- 0014_merge_heads.py | Alembic merge migration that reconciles two divergent migration branches into a single history line | exp: func:upgrade() → None, func:downgrade() → None | dep: typing, alembic
|
||||
- 0015_single_interface.py | Alembic database migration that replaces a JSON array `interfaces` column with `interface_type` string and `requires_port` boolean columns in the `tool_types` table, with dialect-specific data migration for PostgreSQL and SQLite. | exp: func:_get_dialect() → str, call:op.get_bind, func:upgrade() → None, call:_get_dialect, call:op.add_column, call:sa.Column, call:sa.String, call:sa.Boolean, call:op.execute, call:op.alter_column, call:op.drop_column, call:op.create_check_constraint, call:sa.text, func:downgrade() → None, call:_get_dialect, call:op.drop_constraint, call:op.add_column, call:sa.Column, call:postgresql.JSONB, call:sa.Text, call:op.execute, call:sa.JSON, call:op.drop_column | dep: typing, alembic, sqlalchemy.dialects, sqlalchemy, postgresql (dialect)
|
||||
- 069d3da4dc9b_add_ssh_key_id_to_config_profiles.py | Alembic database migration that adds a nullable UUID foreign key column `ssh_key_id` to the `config_profiles` table referencing `ssh_keys.id` with SET NULL on delete | exp: func:upgrade() → None, call:op.add_column, call:sa.Column, call:sa.Uuid, call:sa.ForeignKey, func:downgrade() → None, call:op.drop_column | dep: alembic, sqlalchemy
|
||||
- 20260527160017_add_pi_agent_tool_type.py | Alembic database migration that adds a "pi-agent" terminal-based coding tool type to a tool_types table with Docker configuration templates | exp: func:upgrade() → None, call:op.get_bind, call:conn.execute( sa.text("SELECT id FROM tool_types WHERE name = 'pi-agent'") ).fetchone, call:sa.text, call:json.dumps, func:downgrade() → None, call:op.get_bind, call:conn.execute, call:sa.text | dep: json, typing, alembic, uuid, sqlalchemy
|
||||
- 2026_05_22_add_clone_mode.py | Alembic database migration that adds ssh_key_id foreign key to git_repositories table and clone_mode/branch columns to tool_instances table | exp: func:upgrade() → None, call:op.add_column, call:sa.Column, call:postgresql.UUID, call:op.create_foreign_key, call:sa.String, func:downgrade() → None, call:op.drop_column, call:op.drop_constraint | dep: alembic, sqlalchemy.dialects, sqlalchemy, sqlalchemy.dialects.postgresql
|
||||
- 2026_05_23_remove_is_builtin.py | Alembic database migration to remove the `is_builtin` column from the `tool_types` table | exp: func:upgrade() → None, call:op.execute, func:downgrade() → None, call:op.add_column, call:sa.Column, call:sa.Boolean | dep: alembic, sqlalchemy
|
||||
- 2026_05_24_220141_add_startup_command.py | Alembic database migration that adds a nullable `startup_command` text column to the `tool_types` table. | exp: func:upgrade() → None, call:op.add_column, call:sa.Column, call:sa.Text, func:downgrade() → None, call:op.drop_column | dep: typing, alembic, sqlalchemy
|
||||
- 2026_05_24_add_config_profiles.py | Alembic database migration that creates config_profiles and config_profile_includes tables with indexes, and adds a foreign key column to tool_instances for managing user configuration profiles. | exp: func:upgrade() → None, call:op.create_table, call:sa.Column, call:postgresql.UUID, call:sa.text, call:sa.ForeignKey, call:sa.String, call:sa.Text, call:postgresql.JSONB, call:sa.Boolean, call:sa.DateTime, call:sa.PrimaryKeyConstraint, call:sa.UniqueConstraint, call:op.create_index, call:sa.Integer, call:op.add_column, func:downgrade() → None, call:op.drop_index, call:op.drop_column, call:op.drop_table | dep: typing, alembic, sqlalchemy.dialects, sqlalchemy, postgresql dialect
|
||||
- 2026_05_26_add_git_mounts.py | Alembic database migration that adds a git_mounts JSON column to the config_profiles table | exp: func:upgrade() → None, call:op.add_column, call:sa.Column, call:sa.JSON, func:downgrade() → None, call:op.drop_column | dep: typing, alembic, sqlalchemy
|
||||
- 2026_05_27_external_repos.py | Alembic database migration that makes project_id nullable in git_repositories table to support external repositories and expands alembic_version version_num column to 64 characters. | exp: func:upgrade() → None, call:op.execute, call:op.alter_column, call:sa.UUID, func:downgrade() → None, call:op.alter_column, call:sa.UUID, call:op.execute | dep: typing, alembic, sqlalchemy
|
||||
- 2026_05_28_add_monitoring_tables.py | Alembic database migration that creates monitoring tables (instance_events and health_checks) with indexes for tracking tool instance events and health checks | exp: func:upgrade() → None, call:op.create_table, call:sa.Column, call:sa.Uuid, call:sa.String, call:sa.Text, call:sa.JSON, call:sa.DateTime, call:sa.func.now, call:sa.ForeignKeyConstraint, call:sa.PrimaryKeyConstraint, call:op.create_index, call:sa.Boolean, call:sa.Integer, func:downgrade() → None, call:op.drop_index, call:op.drop_table | dep: collections.abc, alembic, sqlalchemy
|
||||
- 2026_05_28_add_terminal_sessions_table.py | Alembic database migration that creates a terminal_sessions table with tracking columns and foreign key to tool_instances | exp: func:upgrade() → None, call:op.create_table, call:sa.Column, call:sa.UUID, call:sa.String, call:sa.DateTime, call:sa.text, call:sa.ForeignKeyConstraint, call:sa.PrimaryKeyConstraint, call:op.create_index, call:op.f, func:downgrade() → None, call:op.drop_index, call:op.f, call:op.drop_table | dep: collections.abc, alembic, sqlalchemy
|
||||
- 2026_05_28_add_tool_definition_manifests.py | Alembic database migration that creates a tool_definition_manifests table, adds manifest-related columns to tool_types and tool_instances, and migrates existing pi-agent data from Dockerfile templates to JSON-based manifest definitions | exp: func:upgrade() → None, call:op.get_bind, call:op.create_table, call:sa.Column, call:sa.UUID, call:sa.String, call:sa.Text, call:sa.JSON, call:sa.Boolean, call:sa.TIMESTAMP, call:sa.func.now, call:sa.PrimaryKeyConstraint, call:sa.UniqueConstraint, call:sa.ForeignKeyConstraint, call:sa.CheckConstraint, call:conn.execute, call:sa.text, call:result.fetchone, call:op.add_column, call:op.create_foreign_key, call:op.drop_constraint, call:op.execute, call:json.dumps, call:str, func:downgrade() → None, call:op.get_bind, call:conn.execute, call:sa.text, call:result.fetchone, call:op.drop_column, call:op.drop_constraint, call:op.drop_table | dep: json, uuid, typing, alembic, sqlalchemy
|
||||
- 2026_05_28_drop_tool_configs_and_config_folders.py | Alembic database migration that drops `tool_configs` and `config_folders` tables with conditional existence checks and full downgrade recreation | exp: func:upgrade() → None, call:op.get_bind, call:conn.execute, call:sa.text, call:result.fetchone, call:op.drop_table, func:downgrade() → None, call:op.create_table, call:sa.Column, call:sa.UUID, call:sa.String, call:sa.Text, call:sa.JSON, call:sa.Boolean, call:sa.TIMESTAMP, call:sa.func.now, call:sa.PrimaryKeyConstraint, call:sa.Integer | dep: typing, alembic, sqlalchemy
|
||||
- 2026_05_29_add_notifications_table.py | Alembic database migration that creates a notifications table with user-linked, categorized, severity-graded messages supporting read/dismissed tracking and optimized querying indexes. | exp: func:upgrade() → None, call:op.create_table, call:sa.Column, call:sa.Uuid, call:sa.String, call:sa.Text, call:sa.JSON, call:sa.DateTime, call:sa.func.now, call:sa.ForeignKeyConstraint, call:sa.PrimaryKeyConstraint, call:op.create_index, call:sa.text, func:downgrade() → None, call:op.drop_index, call:op.drop_table | dep: collections.abc, alembic, sqlalchemy
|
||||
- 2026_05_29_add_ssh_key_ids_to_tool_instances.py | Alembic database migration that adds a JSON column named ssh_key_ids to the tool_instances table | exp: func:upgrade() → None, call:op.add_column, call:sa.Column, call:sa.JSON, func:downgrade() → None, call:op.drop_column | dep: alembic, sqlalchemy
|
||||
- 2026_05_29_drop_ssh_key_id_from_config_profiles.py | Alembic database migration that removes the ssh_key_id column from the config_profiles table | exp: func:upgrade() → None, call:op.drop_column, func:downgrade() → None, call:op.add_column, call:sa.Column, call:sa.Uuid, call:sa.ForeignKey | dep: alembic, sqlalchemy
|
||||
- 2026_05_29_fix_code_server_bind_addr.py | Alembic database migration that fixes code-server tool type compose templates by replacing deprecated `--bind-addr` flag with `--host` flag | exp: func:upgrade() → None, call:op.get_bind, call:conn.execute( sa.text(""" SELECT id, compose_template FROM tool_types WHERE name = 'code-server' AND compose_template LIKE '%--bind-addr%' """) ).fetchall, call:sa.text, call:compose_template.replace( "--bind-addr 0.0.0.0:8443", "--host 0.0.0.0" ).replace, call:print, func:downgrade() → None | dep: typing, alembic, sqlalchemy
|
||||
- 2026_05_29_fix_code_server_bind_addr_port.py | Alembic database migration that fixes code-server Docker compose templates and instance files by replacing broken `--host` flags with correct `--bind-addr 0.0.0.0:port` configurations | exp: func:_fix_tool_type_templates(conn) → None, call:conn.execute( sa.text(""" SELECT id, compose_template, default_port FROM tool_types WHERE name = 'code-server' AND compose_template LIKE '%--host%' """) ).fetchall, call:sa.text, call:compose_template.split, call:len, call:line.lstrip, call:new_lines.append, call:"\n".join, call:print, func:_fix_instance_compose_files(conn) → None, call:conn.execute( sa.text(""" SELECT column_name FROM information_schema.columns WHERE table_name = 'tool_instances' AND column_name = 'compose_path' """) ).fetchone, call:sa.text, call:print, call:conn.execute( sa.text(""" SELECT id, compose_path, tool_type_id FROM tool_instances WHERE compose_path IS NOT NULL """) ).fetchall, call:Path, call:path.exists, call:path.read_text, call:conn.execute( sa.text(""" SELECT default_port FROM tool_types WHERE id = :id """), {"id": tool_type_id}, ).fetchone, call:yaml.safe_load, call:data["services"].values, call:path.write_text, call:yaml.dump, func:upgrade() → None, call:op.get_bind, call:_fix_tool_type_templates, call:_fix_instance_compose_files, func:downgrade() → None | dep: typing, alembic, yaml, pathlib, sqlalchemy
|
||||
- 2026_05_29_fix_web_tool_bind_address.py | Alembic database migration that updates code-server and jupyter-notebook tool type compose templates to bind to 0.0.0.0 | exp: func:_fix_code_server_compose(conn) → None, call:conn.execute( sa.text(""" SELECT id, compose_template, definition_type FROM tool_types WHERE name = 'code-server' """) ).fetchone, call:sa.text, call:compose_template.split, call:enumerate, call:len, call:line.lstrip, call:new_lines.append, call:image_line.lstrip, call:new_lines.index, call:new_lines.insert, call:"\n".join, call:print, func:_fix_jupyter_compose(conn) → None, call:conn.execute( sa.text(""" SELECT id, compose_template, definition_type FROM tool_types WHERE name = 'jupyter-notebook' """) ).fetchone, call:sa.text, call:compose_template.split, call:enumerate, call:new_lines.append, call:len, call:line.lstrip, call:"\n".join, call:print, func:upgrade() → None, call:op.get_bind, call:_fix_code_server_compose, call:_fix_jupyter_compose, func:downgrade() → None | dep: typing, alembic, sqlalchemy
|
||||
- 2026_05_29_remove_lsio_command_override.py | Alembic database migration that removes broken command overrides containing --bind-addr or --host flags from LinuxServer.io code-server Docker Compose templates in both database tool_types records and on-disk instance compose files. | exp: func:upgrade() → None, call:op.get_bind, call:conn.execute( sa.text(""" SELECT id, compose_template FROM tool_types WHERE name = 'code-server' """) ).fetchall, call:sa.text, call:yaml.safe_load, call:data["services"].values, call:svc.get, call:yaml.dump, call:print, call:conn.execute( sa.text(""" SELECT column_name FROM information_schema.columns WHERE table_name = 'tool_instances' AND column_name = 'compose_path' """) ).fetchone, call:conn.execute( sa.text(""" SELECT id, compose_path FROM tool_instances WHERE compose_path IS NOT NULL """) ).fetchall, call:Path, call:path.exists, call:path.read_text, call:path.write_text, func:downgrade() → None | dep: collections.abc, alembic, yaml, pathlib, sqlalchemy, pathlib.Path, information_schema
|
||||
- 2026_05_29_remove_ssh_keys_mount_from_manifest.py | Alembic database migration that removes (or restores) the ssh_keys mount from a JSON manifest stored in the tool_definition_manifests table for the pi-agent tool definition. | exp: func:upgrade() → None, call:op.get_bind, call:conn.execute, call:sa.text, call:result.fetchone, call:isinstance, call:json.loads, call:manifest.get, call:len, call:m.get, call:json.dumps, func:downgrade() → None, call:op.get_bind, call:conn.execute, call:sa.text, call:result.fetchone, call:isinstance, call:json.loads, call:manifest.get, call:any, call:m.get, call:mounts.append, call:json.dumps | dep: json, typing, alembic, sqlalchemy
|
||||
- 2026_06_01_add_workspaces.py | Alembic database migration that creates a workspaces table with foreign keys to git_repositories and users, adds indexes, and adds a workspace_id column to tool_instances | exp: func:upgrade() → None, call:op.create_table, call:sa.Column, call:sa.Uuid, call:sa.String, call:sa.ForeignKey, call:sa.DateTime, call:sa.text, call:sa.UniqueConstraint, call:op.create_index, call:op.add_column, func:downgrade() → None, call:op.drop_index, call:op.drop_column, call:op.drop_table | dep: collections.abc, alembic, sqlalchemy
|
||||
- 398082499c30_add_tool_config_fields.py | Alembic database migration that adds five new columns (port_override, start_command, working_directory, environment_variables, volumes) to the tool_configs table with a port range check constraint. | exp: func:upgrade() → None, call:op.add_column, call:sa.Column, call:sa.Integer, 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
|
||||
- 6fc7bfcf199f_merge_remove_is_builtin_and_add_config_.py | Alembic database migration that merges two parallel revision branches (removing is_builtin and adding config_profiles) into a single history line | exp: func:upgrade() → None, func:downgrade() → None | dep: alembic
|
||||
- 86cec91fdb00_merge_profile_resolver_and_workspaces_.py | Alembic database migration that merges two divergent migration branches (profile resolver and workspaces) into a single head | exp: func:upgrade() → None, func:downgrade() → None | dep: alembic
|
||||
- 8ed7dd80973d_create_config_folders_table.py | Alembic database migration that creates a config_folders table with user-owned configuration folders supporting JSONB file storage and project overrides | exp: func:upgrade() → None, call:op.create_table, call:sa.Column, call:postgresql.UUID, call:sa.text, call:sa.ForeignKey, call:sa.String, call:sa.Text, call:postgresql.JSONB, call:sa.Boolean, call:sa.DateTime, call:sa.UniqueConstraint, call:op.create_index, func:downgrade() → None, call:op.drop_index, call:op.drop_table | dep: alembic, sqlalchemy.dialects, sqlalchemy, sqlalchemy.dialects.postgresql
|
||||
- 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.
|
||||
## tags
|
||||
column, table, call:op.drop, key, alembic, downgrade, upgrade, constraint
|
||||
## symbols
|
||||
- upgrade
|
||||
- downgrade
|
||||
- _table_exists
|
||||
- _column_exists
|
||||
- _index_exists
|
||||
- _foreign_key_exists
|
||||
- _foreign_key_names_for_column
|
||||
- _get_dialect
|
||||
## workflows
|
||||
- change versions behavior
|
||||
read: 0001_initial_schema.py, 0002_refresh_tokens.py, 0003_user_configs.py
|
||||
- change versions CLI
|
||||
read: 2026_05_24_220141_add_startup_command.py, 2026_05_29_remove_lsio_command_override.py
|
||||
- change versions config
|
||||
read: 0003_user_configs.py, 0009_tool_configs.py, 0013_add_config_profiles.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,51 @@
|
||||
# apps/api/src (index)
|
||||
dir: apps/api/src
|
||||
|
||||
## role
|
||||
Core application package for the Headquarter API backend service, providing configuration, database connectivity, structured logging, and FastAPI application orchestration.
|
||||
## parent
|
||||
index: apps/api/.pi-map.index.md
|
||||
map: apps/api/.pi-map.md
|
||||
## children
|
||||
- apps/api/src/api
|
||||
index: apps/api/src/api/.pi-map.index.md
|
||||
map: apps/api/src/api/.pi-map.md
|
||||
- apps/api/src/auth
|
||||
index: apps/api/src/auth/.pi-map.index.md
|
||||
map: apps/api/src/auth/.pi-map.md
|
||||
- apps/api/src/models
|
||||
index: apps/api/src/models/.pi-map.index.md
|
||||
map: apps/api/src/models/.pi-map.md
|
||||
- apps/api/src/schemas
|
||||
index: apps/api/src/schemas/.pi-map.index.md
|
||||
map: apps/api/src/schemas/.pi-map.md
|
||||
- apps/api/src/scripts
|
||||
index: apps/api/src/scripts/.pi-map.index.md
|
||||
map: apps/api/src/scripts/.pi-map.md
|
||||
- apps/api/src/seeds
|
||||
index: apps/api/src/seeds/.pi-map.index.md
|
||||
map: apps/api/src/seeds/.pi-map.md
|
||||
- apps/api/src/services
|
||||
index: apps/api/src/services/.pi-map.index.md
|
||||
map: apps/api/src/services/.pi-map.md
|
||||
- apps/api/src/utils
|
||||
index: apps/api/src/utils/.pi-map.index.md
|
||||
map: apps/api/src/utils/.pi-map.md
|
||||
## files
|
||||
- __init__.py
|
||||
- config.py
|
||||
- database.py
|
||||
- logging_config.py
|
||||
- main.py
|
||||
## links
|
||||
index: apps/api/src/.pi-map.index.md
|
||||
map: apps/api/src/.pi-map.md
|
||||
## workflows
|
||||
- change src behavior
|
||||
read: __init__.py, config.py, database.py
|
||||
- change src config
|
||||
read: config.py, logging_config.py
|
||||
- explore src subdirectories
|
||||
index: apps/api/src/api/.pi-map.index.md, apps/api/src/auth/.pi-map.index.md, apps/api/src/models/.pi-map.index.md
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,35 @@
|
||||
# apps/api/src
|
||||
dir: apps/api/src
|
||||
|
||||
index: apps/api/src/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Core application package for the Headquarter API backend service, providing configuration, database connectivity, structured logging, and FastAPI application orchestration.
|
||||
## 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
|
||||
- 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 | FastAPI application entry point that initializes and configures the Headquarter API with routers, middleware, database, health monitoring, and CORS | 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 architecture with Pydantic-based configuration management, async SQLAlchemy with Alembic migrations, structured JSON logging with correlation ID tracing, and modular FastAPI setup with middleware pipeline and health monitoring.
|
||||
## tags
|
||||
src, database, logging, call:logger.info, api, middleware, fastapi, filter
|
||||
## symbols
|
||||
- Settings
|
||||
- CorrelationIdFilter
|
||||
- JSONFormatter
|
||||
- RequestLoggingMiddleware
|
||||
- ExceptionLoggingMiddleware
|
||||
- build_database_url
|
||||
- init_database
|
||||
- filter
|
||||
## workflows
|
||||
- change src behavior
|
||||
read: __init__.py, config.py, database.py
|
||||
- change src config
|
||||
read: config.py, logging_config.py
|
||||
- explore src subdirectories
|
||||
index: apps/api/src/api/.pi-map.index.md, apps/api/src/auth/.pi-map.index.md, apps/api/src/models/.pi-map.index.md
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,40 @@
|
||||
# apps/api/src/api (index)
|
||||
dir: apps/api/src/api
|
||||
|
||||
## role
|
||||
Defines reusable Pydantic validators for API request/response schema validation across the API layer.
|
||||
## parent
|
||||
index: apps/api/src/.pi-map.index.md
|
||||
map: apps/api/src/.pi-map.md
|
||||
## children
|
||||
- apps/api/src/api/config
|
||||
index: apps/api/src/api/config/.pi-map.index.md
|
||||
map: apps/api/src/api/config/.pi-map.md
|
||||
- apps/api/src/api/project
|
||||
index: apps/api/src/api/project/.pi-map.index.md
|
||||
map: apps/api/src/api/project/.pi-map.md
|
||||
- apps/api/src/api/system
|
||||
index: apps/api/src/api/system/.pi-map.index.md
|
||||
map: apps/api/src/api/system/.pi-map.md
|
||||
- apps/api/src/api/tool
|
||||
index: apps/api/src/api/tool/.pi-map.index.md
|
||||
map: apps/api/src/api/tool/.pi-map.md
|
||||
- apps/api/src/api/user
|
||||
index: apps/api/src/api/user/.pi-map.index.md
|
||||
map: apps/api/src/api/user/.pi-map.md
|
||||
- apps/api/src/api/workspace
|
||||
index: apps/api/src/api/workspace/.pi-map.index.md
|
||||
map: apps/api/src/api/workspace/.pi-map.md
|
||||
## files
|
||||
- __init__.py
|
||||
- shared_validators.py
|
||||
## links
|
||||
index: apps/api/src/api/.pi-map.index.md
|
||||
map: apps/api/src/api/.pi-map.md
|
||||
## workflows
|
||||
- change api behavior
|
||||
read: __init__.py, shared_validators.py
|
||||
- explore api subdirectories
|
||||
index: apps/api/src/api/config/.pi-map.index.md, apps/api/src/api/project/.pi-map.index.md, apps/api/src/api/system/.pi-map.index.md
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,30 @@
|
||||
# apps/api/src/api
|
||||
dir: apps/api/src/api
|
||||
|
||||
index: apps/api/src/api/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Defines reusable Pydantic validators for API request/response schema validation across 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
|
||||
Utility module pattern providing shared, composable validation functions using Pydantic's validator system for common container/docker-like domain objects (mounts, volumes, files, env vars).
|
||||
## tags
|
||||
validate, raise:value, error, call:isinstance, mount, api, init, path
|
||||
## symbols
|
||||
- validate_mount_path
|
||||
- validate_files
|
||||
- validate_env_vars
|
||||
- validate_volumes
|
||||
- call:v.startswith
|
||||
- raise:ValueError
|
||||
- call:v.items
|
||||
- call:path.startswith
|
||||
## workflows
|
||||
- change api behavior
|
||||
read: __init__.py, shared_validators.py
|
||||
- explore api subdirectories
|
||||
index: apps/api/src/api/config/.pi-map.index.md, apps/api/src/api/project/.pi-map.index.md, apps/api/src/api/system/.pi-map.index.md
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,24 @@
|
||||
# apps/api/src/api/config (index)
|
||||
dir: apps/api/src/api/config
|
||||
|
||||
## role
|
||||
Exposes REST API endpoints for managing user configuration profiles and settings.
|
||||
## parent
|
||||
index: apps/api/src/api/.pi-map.index.md
|
||||
map: apps/api/src/api/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- config_profiles.py
|
||||
- user_config.py
|
||||
## links
|
||||
index: apps/api/src/api/config/.pi-map.index.md
|
||||
map: apps/api/src/api/config/.pi-map.md
|
||||
## workflows
|
||||
- change config behavior
|
||||
read: __init__.py, config_profiles.py, user_config.py
|
||||
- change config config
|
||||
read: config_profiles.py, user_config.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,31 @@
|
||||
# apps/api/src/api/config
|
||||
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.
|
||||
## 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.
|
||||
## tags
|
||||
config, profile, get, user, includes, call:uuid.uuid, or, default
|
||||
## symbols
|
||||
- list_config_profiles
|
||||
- create_config_profile
|
||||
- get_config_profile
|
||||
- update_config_profile
|
||||
- delete_config_profile
|
||||
- update_profile_includes_endpoint
|
||||
- preview_config_profile
|
||||
- resolve_default_profile_endpoint
|
||||
## workflows
|
||||
- change config behavior
|
||||
read: __init__.py, config_profiles.py, user_config.py
|
||||
- change config config
|
||||
read: config_profiles.py, user_config.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,22 @@
|
||||
# apps/api/src/api/project (index)
|
||||
dir: apps/api/src/api/project
|
||||
|
||||
## role
|
||||
Provides REST API endpoints for project and Git repository management in the backend service.
|
||||
## parent
|
||||
index: apps/api/src/api/.pi-map.index.md
|
||||
map: apps/api/src/api/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- git_repositories.py
|
||||
- projects.py
|
||||
## links
|
||||
index: apps/api/src/api/project/.pi-map.index.md
|
||||
map: apps/api/src/api/project/.pi-map.md
|
||||
## workflows
|
||||
- change project behavior
|
||||
read: __init__.py, git_repositories.py, projects.py
|
||||
## dirty
|
||||
-
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,26 @@
|
||||
# apps/api/src/api/system (index)
|
||||
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.
|
||||
## parent
|
||||
index: apps/api/src/api/.pi-map.index.md
|
||||
map: apps/api/src/api/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- dashboard.py
|
||||
- events.py
|
||||
- health.py
|
||||
- instance_proxy.py
|
||||
- notifications.py
|
||||
- terminal.py
|
||||
## links
|
||||
index: apps/api/src/api/system/.pi-map.index.md
|
||||
map: apps/api/src/api/system/.pi-map.md
|
||||
## workflows
|
||||
- change system behavior
|
||||
read: __init__.py, dashboard.py, events.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,33 @@
|
||||
# apps/api/src/api/system
|
||||
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.
|
||||
## 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)
|
||||
- events.py | Implements an SSE streaming endpoint that delivers instance events to authenticated users with per-user connection limits and keep-alive pings. | exp: func:events_stream(request: Request, user_id) → StreamingResponse, call:_connection_counts.get, call:InstanceEventBus, call:asyncio.Queue, call:queue.put_nowait, call:contextlib.suppress, call:queue.get_nowait, call:event_bus.subscribe, call:asyncio.wait_for, call:queue.get, call:json.dumps, call:unsubscribe, call:max, call:_connection_counts.pop, call:StreamingResponse, call:event_generator, raise:HTTPException, func:event_generator() → AsyncGenerator[str, None], call:InstanceEventBus, call:asyncio.Queue, call:queue.put_nowait, call:contextlib.suppress, call:queue.get_nowait, call:event_bus.subscribe, call:asyncio.wait_for, call:queue.get, call:json.dumps, call:unsubscribe, call:max, call:_connection_counts.get, call:_connection_counts.pop, func:on_event(payload: InstanceEventPayload) → None, call:queue.put_nowait, call:contextlib.suppress, call:queue.get_nowait | dep: asyncio, contextlib, json, uuid, collections.abc, fastapi, fastapi.responses, src.auth.dependencies, src.services.instance.event_bus
|
||||
- health.py | Implements FastAPI health check endpoints for monitoring system status including database connectivity and disk space. | exp: func:health_check() → dict[str, Any], call:HealthChecks, call:time_module.perf_counter, call:SessionLocal, call:session.execute, call:text, call:DatabaseHealth, call:round, call:shutil.disk_usage, call:DiskHealth, call:HealthResponse( status=overall_status, timestamp=datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"), version="0.1.0", checks=checks, uptime_seconds=round(time.time() - _start_time, 2), ).model_dump, call:datetime.now(timezone.utc).isoformat().replace, call:time.time, func:health_check_db() → dict[str, Any], call:time_module.perf_counter, call:SessionLocal, call:session.execute, call:text, call:DatabaseHealthResponse( status="healthy", response_time_ms=round(db_time, 2), ).model_dump, call:round, call:DatabaseHealthResponse( status="unhealthy", response_time_ms=0.0, ).model_dump | dep: time, datetime, typing, fastapi, sqlalchemy, src.database, src.schemas.system, shutil
|
||||
- instance_proxy.py | Proxies HTTP requests from FastAPI endpoints to running containerized tool instances after verifying ownership and status. | exp: func:_proxy_request(request: Request, instance_id: uuid.UUID, path: str, user_id: uuid.UUID, session: AsyncSession) → Response, call:session.get, call:str, call:request.headers.items, call:key.lower, call:httpx.AsyncClient, call:request.body, call:client.request, call:logger.error, call:dict, call:response_headers.pop, call:Response, raise:HTTPException, func:proxy_to_instance(request: Request, instance_id: uuid.UUID, path, user_id, session) → Response, call:_proxy_request | dep: logging, uuid, httpx, fastapi, sqlalchemy.ext.asyncio, src.auth.dependencies, src.models
|
||||
- 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.
|
||||
## tags
|
||||
session, terminal, call:terminal, call:, src, get, response, websocket
|
||||
## symbols
|
||||
- NotificationItem
|
||||
- NotificationListResponse
|
||||
- UnreadCountResponse
|
||||
- MarkAllReadResponse
|
||||
- ClearAllResponse
|
||||
- SessionRef
|
||||
- get_dashboard_summary
|
||||
- events_stream
|
||||
## workflows
|
||||
- change system behavior
|
||||
read: __init__.py, dashboard.py, events.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,25 @@
|
||||
# apps/api/src/api/tool (index)
|
||||
dir: apps/api/src/api/tool
|
||||
|
||||
## role
|
||||
Provides FastAPI REST endpoints for managing the complete lifecycle of containerized tools, including type definitions, instances, sessions, and validation.
|
||||
## parent
|
||||
index: apps/api/src/api/.pi-map.index.md
|
||||
map: apps/api/src/api/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- sessions.py
|
||||
- tool_definitions.py
|
||||
- tool_instances.py
|
||||
- tool_types.py
|
||||
- tool_types_validation.py
|
||||
## links
|
||||
index: apps/api/src/api/tool/.pi-map.index.md
|
||||
map: apps/api/src/api/tool/.pi-map.md
|
||||
## workflows
|
||||
- change tool behavior
|
||||
read: __init__.py, sessions.py, tool_definitions.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,32 @@
|
||||
# apps/api/src/api/tool
|
||||
dir: apps/api/src/api/tool
|
||||
|
||||
index: apps/api/src/api/tool/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Provides FastAPI REST endpoints for managing the complete lifecycle of containerized tools, including type definitions, instances, sessions, and validation.
|
||||
## files
|
||||
- __init__.py | Aggregates and exports tool-related API routers from submodules for centralized access | dep: src.api.tool.sessions, src.api.tool.tool_definitions, src.api.tool.tool_instances, src.api.tool.tool_types
|
||||
- sessions.py | Provides a FastAPI endpoint to retrieve all active tool sessions (running instances) 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
|
||||
- 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 | Defines FastAPI REST endpoints for managing Docker-based tool instances within projects, including CRUD operations, lifecycle control (start/stop/restart), logs, health checks, and tunnel management. | 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: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, 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_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
|
||||
## arch
|
||||
Modular router composition with domain-driven separation (types/instances/sessions/definitions), Docker-centric architecture using compose/dockerfile manifests, and validation-layer pattern for YAML sanitization and structural verification.
|
||||
## tags
|
||||
get, call:, tool, raise:httpexception, user, instance, call:str, call:session.get
|
||||
## symbols
|
||||
- CreateToolDefinitionRequest
|
||||
- UpdateToolDefinitionRequest
|
||||
- get_user_sessions
|
||||
- create_tool_definition
|
||||
- list_tool_definitions
|
||||
- get_tool_definition
|
||||
- update_tool_definition
|
||||
- delete_tool_definition
|
||||
## workflows
|
||||
- change tool behavior
|
||||
read: __init__.py, sessions.py, tool_definitions.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,23 @@
|
||||
# apps/api/src/api/user (index)
|
||||
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.
|
||||
## parent
|
||||
index: apps/api/src/api/.pi-map.index.md
|
||||
map: apps/api/src/api/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- auth.py
|
||||
- ssh_keys.py
|
||||
- users.py
|
||||
## links
|
||||
index: apps/api/src/api/user/.pi-map.index.md
|
||||
map: apps/api/src/api/user/.pi-map.md
|
||||
## workflows
|
||||
- change user behavior
|
||||
read: __init__.py, auth.py, ssh_keys.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,30 @@
|
||||
# apps/api/src/api/user
|
||||
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.
|
||||
## 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.
|
||||
## tags
|
||||
user, get, call:, key, ssh, src, cookie, raise:httpexception
|
||||
## symbols
|
||||
- get_db_session
|
||||
- login
|
||||
- callback
|
||||
- logout
|
||||
- me
|
||||
- _get_fernet
|
||||
- generate_ssh_key_pair
|
||||
- create_ssh_key
|
||||
## workflows
|
||||
- change user behavior
|
||||
read: __init__.py, auth.py, ssh_keys.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,24 @@
|
||||
# apps/api/src/api/workspace (index)
|
||||
dir: apps/api/src/api/workspace
|
||||
|
||||
## role
|
||||
Provides FastAPI REST endpoints for workspace management, file operations, and git integration in user-scoped development environments.
|
||||
## parent
|
||||
index: apps/api/src/api/.pi-map.index.md
|
||||
map: apps/api/src/api/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- workspace_files.py
|
||||
- workspace_git.py
|
||||
- workspace_instances.py
|
||||
- workspaces.py
|
||||
## links
|
||||
index: apps/api/src/api/workspace/.pi-map.index.md
|
||||
map: apps/api/src/api/workspace/.pi-map.md
|
||||
## workflows
|
||||
- change workspace behavior
|
||||
read: __init__.py, workspace_files.py, workspace_git.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,31 @@
|
||||
# apps/api/src/api/workspace
|
||||
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.
|
||||
## 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
|
||||
- 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.
|
||||
## tags
|
||||
workspace, get, raise:httpexception, call:, at.isoformat, git, call:select, call:data.get
|
||||
## symbols
|
||||
- _get_workspace
|
||||
- list_files
|
||||
- get_file_content
|
||||
- write_file
|
||||
- git_status
|
||||
- git_branches
|
||||
- git_commit
|
||||
- git_push
|
||||
## workflows
|
||||
- change workspace behavior
|
||||
read: __init__.py, workspace_files.py, workspace_git.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,24 @@
|
||||
# apps/api/src/auth (index)
|
||||
dir: apps/api/src/auth
|
||||
|
||||
## role
|
||||
Provides authentication and authorization infrastructure for the API, including OIDC/OAuth2 integration, session management, and FastAPI dependency injection.
|
||||
## parent
|
||||
index: apps/api/src/.pi-map.index.md
|
||||
map: apps/api/src/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- cookies.py
|
||||
- dependencies.py
|
||||
- oidc.py
|
||||
- session.py
|
||||
## links
|
||||
index: apps/api/src/auth/.pi-map.index.md
|
||||
map: apps/api/src/auth/.pi-map.md
|
||||
## workflows
|
||||
- change auth behavior
|
||||
read: __init__.py, cookies.py, dependencies.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,31 @@
|
||||
# apps/api/src/auth
|
||||
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.
|
||||
## 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
|
||||
- dependencies.py | Provides FastAPI dependency functions for database sessions, user authentication, and project authorization. | exp: func:get_db_session(), call:SessionLocal, func:get_current_user_id(session_cookie) → uuid.UUID, call:Settings, call:decode_session_cookie, call:uuid.UUID, call:str, raise:HTTPException, func:get_current_user(session_cookie, db_session) → User, call:Settings, call:decode_session_cookie, call:uuid.UUID, call:str, call:db_session.get, raise:HTTPException, func:_get_user(session: AsyncSession, user_id: uuid.UUID) → User, call:session.get, raise:HTTPException, func:_get_owned_project(project_id: uuid.UUID, user_id: uuid.UUID, session: AsyncSession) → "Project", call:session.get, raise:HTTPException | dep: uuid, typing, fastapi, sqlalchemy.ext.asyncio, src.auth.session, src.config, src.database, src.models.project, src.models.user, sqlalchemy
|
||||
- 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.
|
||||
## tags
|
||||
session, src, cookie, user, get, base64url, raise:httpexception, call:
|
||||
## symbols
|
||||
- build_cookie_options
|
||||
- get_db_session
|
||||
- get_current_user_id
|
||||
- get_current_user
|
||||
- _get_user
|
||||
- _get_owned_project
|
||||
- build_login_redirect_url
|
||||
- exchange_code_for_tokens
|
||||
## workflows
|
||||
- change auth behavior
|
||||
read: __init__.py, cookies.py, dependencies.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,37 @@
|
||||
# apps/api/src/models (index)
|
||||
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.
|
||||
## parent
|
||||
index: apps/api/src/.pi-map.index.md
|
||||
map: apps/api/src/.pi-map.md
|
||||
## children
|
||||
- apps/api/src/models/config
|
||||
index: apps/api/src/models/config/.pi-map.index.md
|
||||
map: apps/api/src/models/config/.pi-map.md
|
||||
- apps/api/src/models/project
|
||||
index: apps/api/src/models/project/.pi-map.index.md
|
||||
map: apps/api/src/models/project/.pi-map.md
|
||||
- apps/api/src/models/system
|
||||
index: apps/api/src/models/system/.pi-map.index.md
|
||||
map: apps/api/src/models/system/.pi-map.md
|
||||
- apps/api/src/models/tool
|
||||
index: apps/api/src/models/tool/.pi-map.index.md
|
||||
map: apps/api/src/models/tool/.pi-map.md
|
||||
- apps/api/src/models/user
|
||||
index: apps/api/src/models/user/.pi-map.index.md
|
||||
map: apps/api/src/models/user/.pi-map.md
|
||||
## files
|
||||
- __init__.py
|
||||
- base.py
|
||||
## links
|
||||
index: apps/api/src/models/.pi-map.index.md
|
||||
map: apps/api/src/models/.pi-map.md
|
||||
## workflows
|
||||
- change models behavior
|
||||
read: __init__.py, base.py
|
||||
- explore models subdirectories
|
||||
index: apps/api/src/models/config/.pi-map.index.md, apps/api/src/models/project/.pi-map.index.md, apps/api/src/models/system/.pi-map.index.md
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,25 @@
|
||||
# apps/api/src/models
|
||||
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.
|
||||
## 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.
|
||||
## tags
|
||||
models, src, base, project, system, user, mixin, tool
|
||||
## symbols
|
||||
- Base
|
||||
- UUIDPrimaryKeyMixin
|
||||
- TimestampMixin
|
||||
## workflows
|
||||
- change models behavior
|
||||
read: __init__.py, base.py
|
||||
- explore models subdirectories
|
||||
index: apps/api/src/models/config/.pi-map.index.md, apps/api/src/models/project/.pi-map.index.md, apps/api/src/models/system/.pi-map.index.md
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,23 @@
|
||||
# apps/api/src/models/config (index)
|
||||
dir: apps/api/src/models/config
|
||||
|
||||
## role
|
||||
Provides SQLAlchemy ORM models for managing configuration profiles and their hierarchical includes in the API application.
|
||||
## parent
|
||||
index: apps/api/src/models/.pi-map.index.md
|
||||
map: apps/api/src/models/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- config_profile.py
|
||||
## links
|
||||
index: apps/api/src/models/config/.pi-map.index.md
|
||||
map: apps/api/src/models/config/.pi-map.md
|
||||
## workflows
|
||||
- change config behavior
|
||||
read: __init__.py, config_profile.py
|
||||
- change config config
|
||||
read: config_profile.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,24 @@
|
||||
# apps/api/src/models/config
|
||||
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.
|
||||
## 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.
|
||||
## tags
|
||||
config, src, models, profile, sqlalchemy, init, orm, mounts
|
||||
## symbols
|
||||
- ConfigProfile
|
||||
- ConfigProfileInclude
|
||||
## workflows
|
||||
- change config behavior
|
||||
read: __init__.py, config_profile.py
|
||||
- change config config
|
||||
read: config_profile.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,23 @@
|
||||
# apps/api/src/models/project (index)
|
||||
dir: apps/api/src/models/project
|
||||
|
||||
## role
|
||||
Defines the core data models for project-related entities (GitRepository, Project, Workspace) using SQLAlchemy ORM.
|
||||
## parent
|
||||
index: apps/api/src/models/.pi-map.index.md
|
||||
map: apps/api/src/models/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- git_repository.py
|
||||
- project.py
|
||||
- workspace.py
|
||||
## links
|
||||
index: apps/api/src/models/project/.pi-map.index.md
|
||||
map: apps/api/src/models/project/.pi-map.md
|
||||
## workflows
|
||||
- change project behavior
|
||||
read: __init__.py, git_repository.py, project.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,25 @@
|
||||
# apps/api/src/models/project
|
||||
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.
|
||||
## 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.
|
||||
## tags
|
||||
models, src, project, sqlalchemy, git, user, workspace, orm
|
||||
## symbols
|
||||
- GitRepository
|
||||
- Project
|
||||
- Workspace
|
||||
## workflows
|
||||
- change project behavior
|
||||
read: __init__.py, git_repository.py, project.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,24 @@
|
||||
# apps/api/src/models/system (index)
|
||||
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.
|
||||
## parent
|
||||
index: apps/api/src/models/.pi-map.index.md
|
||||
map: apps/api/src/models/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- health_check.py
|
||||
- instance_event.py
|
||||
- notification.py
|
||||
- terminal_session.py
|
||||
## links
|
||||
index: apps/api/src/models/system/.pi-map.index.md
|
||||
map: apps/api/src/models/system/.pi-map.md
|
||||
## workflows
|
||||
- change system behavior
|
||||
read: __init__.py, health_check.py, instance_event.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,27 @@
|
||||
# apps/api/src/models/system
|
||||
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.
|
||||
## 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
|
||||
- instance_event.py | Defines a SQLAlchemy ORM model for auditing instance lifecycle events with metadata, status tracking, and user attribution. | exp: class:InstanceEvent | dep: uuid, datetime, typing, sqlalchemy, sqlalchemy.orm, src.models.base
|
||||
- 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).
|
||||
## tags
|
||||
sqlalchemy, src, models, model, orm, system, notification, health
|
||||
## symbols
|
||||
- HealthCheck
|
||||
- InstanceEvent
|
||||
- Notification
|
||||
- TerminalSessionModel
|
||||
## workflows
|
||||
- change system behavior
|
||||
read: __init__.py, health_check.py, instance_event.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,23 @@
|
||||
# apps/api/src/models/tool (index)
|
||||
dir: apps/api/src/models/tool
|
||||
|
||||
## role
|
||||
Defines SQLAlchemy ORM models for managing tool definitions, instances, and types in a container-based deployment system.
|
||||
## parent
|
||||
index: apps/api/src/models/.pi-map.index.md
|
||||
map: apps/api/src/models/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- tool_definition_manifest.py
|
||||
- tool_instance.py
|
||||
- tool_type.py
|
||||
## links
|
||||
index: apps/api/src/models/tool/.pi-map.index.md
|
||||
map: apps/api/src/models/tool/.pi-map.md
|
||||
## workflows
|
||||
- change tool behavior
|
||||
read: __init__.py, tool_definition_manifest.py, tool_instance.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,25 @@
|
||||
# apps/api/src/models/tool
|
||||
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.
|
||||
## 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_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.
|
||||
## tags
|
||||
tool, models, src, sqlalchemy, orm, definition, manifest, base
|
||||
## symbols
|
||||
- ToolDefinitionManifest
|
||||
- ToolInstance
|
||||
- ToolType
|
||||
## workflows
|
||||
- change tool behavior
|
||||
read: __init__.py, tool_definition_manifest.py, tool_instance.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,25 @@
|
||||
# apps/api/src/models/user (index)
|
||||
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.
|
||||
## parent
|
||||
index: apps/api/src/models/.pi-map.index.md
|
||||
map: apps/api/src/models/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- ssh_key.py
|
||||
- user.py
|
||||
- user_config.py
|
||||
## links
|
||||
index: apps/api/src/models/user/.pi-map.index.md
|
||||
map: apps/api/src/models/user/.pi-map.md
|
||||
## workflows
|
||||
- change user behavior
|
||||
read: __init__.py, ssh_key.py, user.py
|
||||
- change user config
|
||||
read: user_config.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,27 @@
|
||||
# apps/api/src/models/user
|
||||
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.
|
||||
## 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.
|
||||
## tags
|
||||
user, src, models, sqlalchemy, sshkey, orm, model, ssh
|
||||
## symbols
|
||||
- SSHKey
|
||||
- User
|
||||
- UserConfig
|
||||
## workflows
|
||||
- change user behavior
|
||||
read: __init__.py, ssh_key.py, user.py
|
||||
- change user config
|
||||
read: user_config.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,36 @@
|
||||
# apps/api/src/schemas (index)
|
||||
dir: apps/api/src/schemas
|
||||
|
||||
## role
|
||||
Defines Pydantic schemas for data validation, serialization, and API request/response models in the FastAPI application.
|
||||
## parent
|
||||
index: apps/api/src/.pi-map.index.md
|
||||
map: apps/api/src/.pi-map.md
|
||||
## children
|
||||
- apps/api/src/schemas/config
|
||||
index: apps/api/src/schemas/config/.pi-map.index.md
|
||||
map: apps/api/src/schemas/config/.pi-map.md
|
||||
- apps/api/src/schemas/project
|
||||
index: apps/api/src/schemas/project/.pi-map.index.md
|
||||
map: apps/api/src/schemas/project/.pi-map.md
|
||||
- apps/api/src/schemas/system
|
||||
index: apps/api/src/schemas/system/.pi-map.index.md
|
||||
map: apps/api/src/schemas/system/.pi-map.md
|
||||
- apps/api/src/schemas/tool
|
||||
index: apps/api/src/schemas/tool/.pi-map.index.md
|
||||
map: apps/api/src/schemas/tool/.pi-map.md
|
||||
- apps/api/src/schemas/user
|
||||
index: apps/api/src/schemas/user/.pi-map.index.md
|
||||
map: apps/api/src/schemas/user/.pi-map.md
|
||||
## files
|
||||
- __init__.py
|
||||
## links
|
||||
index: apps/api/src/schemas/.pi-map.index.md
|
||||
map: apps/api/src/schemas/.pi-map.md
|
||||
## workflows
|
||||
- change schemas behavior
|
||||
read: __init__.py
|
||||
- explore schemas subdirectories
|
||||
index: apps/api/src/schemas/config/.pi-map.index.md, apps/api/src/schemas/project/.pi-map.index.md, apps/api/src/schemas/system/.pi-map.index.md
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,22 @@
|
||||
# apps/api/src/schemas
|
||||
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.
|
||||
## 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.
|
||||
## tags
|
||||
init, empty, functionality
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
- change schemas behavior
|
||||
read: __init__.py
|
||||
- explore schemas subdirectories
|
||||
index: apps/api/src/schemas/config/.pi-map.index.md, apps/api/src/schemas/project/.pi-map.index.md, apps/api/src/schemas/system/.pi-map.index.md
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,23 @@
|
||||
# apps/api/src/schemas/config (index)
|
||||
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.
|
||||
## parent
|
||||
index: apps/api/src/schemas/.pi-map.index.md
|
||||
map: apps/api/src/schemas/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- config_profile.py
|
||||
## links
|
||||
index: apps/api/src/schemas/config/.pi-map.index.md
|
||||
map: apps/api/src/schemas/config/.pi-map.md
|
||||
## workflows
|
||||
- change config behavior
|
||||
read: __init__.py, config_profile.py
|
||||
- change config config
|
||||
read: config_profile.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,30 @@
|
||||
# apps/api/src/schemas/config
|
||||
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.
|
||||
## 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`.
|
||||
## tags
|
||||
profile, config, git, mount, update, validate, response, item
|
||||
## symbols
|
||||
- GitMountMapping
|
||||
- GitMountItem
|
||||
- MountItem
|
||||
- ConfigProfileCreate
|
||||
- ConfigProfileUpdate
|
||||
- ConfigProfileIncludeUpdate
|
||||
- ConfigProfileResponse
|
||||
- DefaultProfilesUpdate
|
||||
## workflows
|
||||
- change config behavior
|
||||
read: __init__.py, config_profile.py
|
||||
- change config config
|
||||
read: config_profile.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,23 @@
|
||||
# apps/api/src/schemas/project (index)
|
||||
dir: apps/api/src/schemas/project
|
||||
|
||||
## role
|
||||
Provides Pydantic data validation schemas for project-related API endpoints including projects, Git repositories, and SSH keys.
|
||||
## parent
|
||||
index: apps/api/src/schemas/.pi-map.index.md
|
||||
map: apps/api/src/schemas/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- git_repository.py
|
||||
- project.py
|
||||
- ssh_key.py
|
||||
## links
|
||||
index: apps/api/src/schemas/project/.pi-map.index.md
|
||||
map: apps/api/src/schemas/project/.pi-map.md
|
||||
## workflows
|
||||
- change project behavior
|
||||
read: __init__.py, git_repository.py, project.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,30 @@
|
||||
# apps/api/src/schemas/project
|
||||
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.
|
||||
## 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.
|
||||
## tags
|
||||
response, request, project, create, update, sshkey, pydantic, schemas
|
||||
## symbols
|
||||
- GitRepositoryCreate
|
||||
- URLParseRequest
|
||||
- URLParseResponse
|
||||
- GitRepositoryResponse
|
||||
- UpdateSSHKeyRequest
|
||||
- FileListResponse
|
||||
- FileContentResponse
|
||||
- BranchesResponse
|
||||
## workflows
|
||||
- change project behavior
|
||||
read: __init__.py, git_repository.py, project.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,21 @@
|
||||
# apps/api/src/schemas/system (index)
|
||||
dir: apps/api/src/schemas/system
|
||||
|
||||
## role
|
||||
Provides Pydantic schemas for system health monitoring endpoints in the API.
|
||||
## parent
|
||||
index: apps/api/src/schemas/.pi-map.index.md
|
||||
map: apps/api/src/schemas/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- health.py
|
||||
## links
|
||||
index: apps/api/src/schemas/system/.pi-map.index.md
|
||||
map: apps/api/src/schemas/system/.pi-map.md
|
||||
## workflows
|
||||
- change system behavior
|
||||
read: __init__.py, health.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,25 @@
|
||||
# apps/api/src/schemas/system
|
||||
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.
|
||||
## 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.
|
||||
## tags
|
||||
health, database, response, system, disk, check, schemas, init
|
||||
## symbols
|
||||
- DatabaseHealth
|
||||
- DiskHealth
|
||||
- HealthChecks
|
||||
- HealthResponse
|
||||
- DatabaseHealthResponse
|
||||
## workflows
|
||||
- change system behavior
|
||||
read: __init__.py, health.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,22 @@
|
||||
# apps/api/src/schemas/tool (index)
|
||||
dir: apps/api/src/schemas/tool
|
||||
|
||||
## role
|
||||
Provides Pydantic data validation schemas for tool-related API operations including tool types and instances.
|
||||
## parent
|
||||
index: apps/api/src/schemas/.pi-map.index.md
|
||||
map: apps/api/src/schemas/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- tool_instance.py
|
||||
- tool_type.py
|
||||
## links
|
||||
index: apps/api/src/schemas/tool/.pi-map.index.md
|
||||
map: apps/api/src/schemas/tool/.pi-map.md
|
||||
## workflows
|
||||
- change tool behavior
|
||||
read: __init__.py, tool_instance.py, tool_type.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,27 @@
|
||||
# apps/api/src/schemas/tool
|
||||
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.
|
||||
## 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
|
||||
## 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.
|
||||
## tags
|
||||
tool, type, request, instance, schemas, create, pydantic, response
|
||||
## symbols
|
||||
- CreateInstanceRequest
|
||||
- StartInstanceRequest
|
||||
- ToolTypeCreate
|
||||
- ToolTypeUpdate
|
||||
- ToolTypeResponse
|
||||
- ToolTypeValidateRequest
|
||||
## workflows
|
||||
- change tool behavior
|
||||
read: __init__.py, tool_instance.py, tool_type.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,24 @@
|
||||
# apps/api/src/schemas/user (index)
|
||||
dir: apps/api/src/schemas/user
|
||||
|
||||
## role
|
||||
Provides centralized 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
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- user.py
|
||||
- user_config.py
|
||||
## links
|
||||
index: apps/api/src/schemas/user/.pi-map.index.md
|
||||
map: apps/api/src/schemas/user/.pi-map.md
|
||||
## workflows
|
||||
- change user behavior
|
||||
read: __init__.py, user.py, user_config.py
|
||||
- change user config
|
||||
read: user_config.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,27 @@
|
||||
# apps/api/src/schemas/user
|
||||
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.
|
||||
## 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.
|
||||
## tags
|
||||
user, schemas, response, update, config, pydantic, profile, src
|
||||
## symbols
|
||||
- UserProfileResponse
|
||||
- UserProfileUpdate
|
||||
- UserConfigResponse
|
||||
- UserConfigUpdate
|
||||
## workflows
|
||||
- change user behavior
|
||||
read: __init__.py, user.py, user_config.py
|
||||
- change user config
|
||||
read: user_config.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,21 @@
|
||||
# apps/api/src/scripts (index)
|
||||
dir: apps/api/src/scripts
|
||||
|
||||
## role
|
||||
Provides utility scripts for administrative and setup tasks for the API application.
|
||||
## parent
|
||||
index: apps/api/src/.pi-map.index.md
|
||||
map: apps/api/src/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- seed.py
|
||||
## links
|
||||
index: apps/api/src/scripts/.pi-map.index.md
|
||||
map: apps/api/src/scripts/.pi-map.md
|
||||
## workflows
|
||||
- change scripts behavior
|
||||
read: __init__.py, seed.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,28 @@
|
||||
# apps/api/src/scripts
|
||||
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.
|
||||
## 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.
|
||||
## tags
|
||||
seed, user, database, sqlalchemy, package, init, call:build, call:session.scalar
|
||||
## symbols
|
||||
- build_seed_user
|
||||
- seed_database
|
||||
- run
|
||||
- main
|
||||
- call:build_seed_user
|
||||
- call:session.scalar
|
||||
- call:select(User).where
|
||||
- call:User
|
||||
## workflows
|
||||
- change scripts behavior
|
||||
read: __init__.py, seed.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,21 @@
|
||||
# apps/api/src/seeds (index)
|
||||
dir: apps/api/src/seeds
|
||||
|
||||
## role
|
||||
Provides database seeding utilities for initializing built-in tool types in the API application.
|
||||
## parent
|
||||
index: apps/api/src/.pi-map.index.md
|
||||
map: apps/api/src/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- builtin_tool_types.py
|
||||
## links
|
||||
index: apps/api/src/seeds/.pi-map.index.md
|
||||
map: apps/api/src/seeds/.pi-map.md
|
||||
## workflows
|
||||
- change seeds behavior
|
||||
read: __init__.py, builtin_tool_types.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,28 @@
|
||||
# apps/api/src/seeds
|
||||
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.
|
||||
## 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.
|
||||
## tags
|
||||
tool, types, table, exists, builtin, call:tool, database, init
|
||||
## symbols
|
||||
- _table_exists
|
||||
- seed_builtin_tool_types
|
||||
- call:session.execute
|
||||
- call:text
|
||||
- call:result.scalar
|
||||
- call:SessionLocal
|
||||
- call:_table_exists
|
||||
- call:logger.warning
|
||||
## workflows
|
||||
- change seeds behavior
|
||||
read: __init__.py, builtin_tool_types.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,42 @@
|
||||
# apps/api/src/services (index)
|
||||
dir: apps/api/src/services
|
||||
|
||||
## role
|
||||
Initializes the services directory as a Python package for business logic modules.
|
||||
## parent
|
||||
index: apps/api/src/.pi-map.index.md
|
||||
map: apps/api/src/.pi-map.md
|
||||
## children
|
||||
- apps/api/src/services/config
|
||||
index: apps/api/src/services/config/.pi-map.index.md
|
||||
map: apps/api/src/services/config/.pi-map.md
|
||||
- apps/api/src/services/docker
|
||||
index: apps/api/src/services/docker/.pi-map.index.md
|
||||
map: apps/api/src/services/docker/.pi-map.md
|
||||
- apps/api/src/services/git
|
||||
index: apps/api/src/services/git/.pi-map.index.md
|
||||
map: apps/api/src/services/git/.pi-map.md
|
||||
- apps/api/src/services/instance
|
||||
index: apps/api/src/services/instance/.pi-map.index.md
|
||||
map: apps/api/src/services/instance/.pi-map.md
|
||||
- apps/api/src/services/shared
|
||||
index: apps/api/src/services/shared/.pi-map.index.md
|
||||
map: apps/api/src/services/shared/.pi-map.md
|
||||
- apps/api/src/services/terminal
|
||||
index: apps/api/src/services/terminal/.pi-map.index.md
|
||||
map: apps/api/src/services/terminal/.pi-map.md
|
||||
- apps/api/src/services/tool
|
||||
index: apps/api/src/services/tool/.pi-map.index.md
|
||||
map: apps/api/src/services/tool/.pi-map.md
|
||||
## files
|
||||
- __init__.py
|
||||
## links
|
||||
index: apps/api/src/services/.pi-map.index.md
|
||||
map: apps/api/src/services/.pi-map.md
|
||||
## workflows
|
||||
- change services behavior
|
||||
read: __init__.py
|
||||
- explore services subdirectories
|
||||
index: apps/api/src/services/config/.pi-map.index.md, apps/api/src/services/docker/.pi-map.index.md, apps/api/src/services/git/.pi-map.index.md
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,22 @@
|
||||
# apps/api/src/services
|
||||
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.
|
||||
## files
|
||||
- __init__.py | Empty file with no functionality
|
||||
## arch
|
||||
Standard Python package structure using empty __init__.py for namespace declaration.
|
||||
## tags
|
||||
init, empty, functionality
|
||||
## symbols
|
||||
-
|
||||
## workflows
|
||||
- change services behavior
|
||||
read: __init__.py
|
||||
- explore services subdirectories
|
||||
index: apps/api/src/services/config/.pi-map.index.md, apps/api/src/services/docker/.pi-map.index.md, apps/api/src/services/git/.pi-map.index.md
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,25 @@
|
||||
# apps/api/src/services/config (index)
|
||||
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.
|
||||
## parent
|
||||
index: apps/api/src/services/.pi-map.index.md
|
||||
map: apps/api/src/services/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- config_profile_resolver.py
|
||||
- crud_service.py
|
||||
- resolver_service.py
|
||||
## links
|
||||
index: apps/api/src/services/config/.pi-map.index.md
|
||||
map: apps/api/src/services/config/.pi-map.md
|
||||
## workflows
|
||||
- change config behavior
|
||||
read: __init__.py, config_profile_resolver.py, crud_service.py
|
||||
- change config config
|
||||
read: config_profile_resolver.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,32 @@
|
||||
# apps/api/src/services/config
|
||||
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.
|
||||
## 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.
|
||||
## tags
|
||||
profile, call:, call:select, git, merge, call:str, call:session.execute, mounts
|
||||
## symbols
|
||||
- ConfigProfileCycleError
|
||||
- ConfigProfileNotFoundError
|
||||
- ResolvedMount
|
||||
- ResolvedProfile
|
||||
- _detect_cycle
|
||||
- _merge_env_vars
|
||||
- _merge_runtime_hints
|
||||
- _merge_files
|
||||
## workflows
|
||||
- change config behavior
|
||||
read: __init__.py, config_profile_resolver.py, crud_service.py
|
||||
- change config config
|
||||
read: config_profile_resolver.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,26 @@
|
||||
# apps/api/src/services/docker (index)
|
||||
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.
|
||||
## parent
|
||||
index: apps/api/src/services/.pi-map.index.md
|
||||
map: apps/api/src/services/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- compose.py
|
||||
- config_staging.py
|
||||
- container.py
|
||||
- tunnel.py
|
||||
## links
|
||||
index: apps/api/src/services/docker/.pi-map.index.md
|
||||
map: apps/api/src/services/docker/.pi-map.md
|
||||
## workflows
|
||||
- change docker behavior
|
||||
read: __init__.py, compose.py, config_staging.py
|
||||
- change docker config
|
||||
read: config_staging.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,33 @@
|
||||
# apps/api/src/services/docker
|
||||
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.
|
||||
## 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
|
||||
- config_staging.py | Stages configuration files into instance directories with security checks for path traversal. | exp: func:ensure_instance_directory(instance_id: str, base_path) → str, call:Settings, call:Path, call:instance_dir.mkdir, call:str, call:instance_dir.absolute, func:write_env_file(instance_dir: str, env_vars: dict[str, str]) → str, call:Path, call:env_vars.items, call:env_path.write_text, call:"\n".join, call:str, func:write_config_files(instance_dir: str, files: dict[str, str]) → None, call:Path, call:files.items, call:full_path.resolve().relative_to, call:instance_path.resolve, call:full_path.parent.mkdir, call:full_path.write_text, raise:ValueError | dep: logging, pathlib, src.config, src.config.Settings
|
||||
- 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.
|
||||
## tags
|
||||
tunnel, container, call:subprocess.run, get, name, call:, network, call:result.stdout.strip
|
||||
## symbols
|
||||
- sort_volumes_by_specificity
|
||||
- _target_depth
|
||||
- render_compose_template
|
||||
- write_compose_file
|
||||
- execute_compose_command
|
||||
- ensure_instance_directory
|
||||
- write_env_file
|
||||
- write_config_files
|
||||
## workflows
|
||||
- change docker behavior
|
||||
read: __init__.py, compose.py, config_staging.py
|
||||
- change docker config
|
||||
read: config_staging.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,24 @@
|
||||
# apps/api/src/services/git (index)
|
||||
dir: apps/api/src/services/git
|
||||
|
||||
## role
|
||||
Provides git repository operations for workspace management including cloning, authentication, and common git commands
|
||||
## parent
|
||||
index: apps/api/src/services/.pi-map.index.md
|
||||
map: apps/api/src/services/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- clone.py
|
||||
- git_operations.py
|
||||
- git_service.py
|
||||
- operations.py
|
||||
## links
|
||||
index: apps/api/src/services/git/.pi-map.index.md
|
||||
map: apps/api/src/services/git/.pi-map.md
|
||||
## workflows
|
||||
- change git behavior
|
||||
read: __init__.py, clone.py, git_operations.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,31 @@
|
||||
# apps/api/src/services/git
|
||||
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
|
||||
## 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
|
||||
- git_operations.py | Provides asynchronous git operations (status, commit, push, pull, fetch, checkout, history, branches) scoped to a workspace directory by wrapping git CLI commands. | exp: class:GitStatus, class:Commit, class:GitOperations, method:__init__(self, workspace: Workspace) → None, method:_run(self, *cmd: str) → tuple[int, str, str], call:asyncio.create_subprocess_exec, call:proc.communicate, call:stdout.decode, call:stderr.decode, method:status(self) → GitStatus, call:self._run, call:stdout.splitlines, call:line.startswith, call:line[3:].strip, 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:untracked.append, call:deleted.append, call:added.append, call:modified.append, call:GitStatus, method:commit(self, message: str) → None, call:self._run, call:logger.info, raise:RuntimeError, method:push(self) → None, call:self._run, call:logger.info, raise:RuntimeError, method:pull(self) → None, call:self._run, call:logger.info, raise:RuntimeError, method:fetch(self) → None, call:self._run, call:logger.info, raise:RuntimeError, method:checkout(self, branch: str) → None, call:self._run, call:logger.info, raise:RuntimeError, method:history(self, path, limit) → list[Commit], call:cmd.extend, call:self._run, call:stdout.strip().splitlines, call:line.split, call:len, call:commits.append, call:Commit, raise:RuntimeError, method:branches(self) → tuple[list[str], str], call:self._run, call:stdout.strip().splitlines, call:line.strip, call:line.startswith, call:line.endswith, call:line.replace, call:branches.append, raise:RuntimeError | dep: asyncio, logging, dataclasses, src.models, src.models.Workspace
|
||||
- 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
|
||||
## tags
|
||||
git, raise:runtime, error, run, call:self., clone, call:subprocess.run, ssh
|
||||
## symbols
|
||||
- GitStatus
|
||||
- Commit
|
||||
- GitOperations
|
||||
- GitService
|
||||
- clone_repository
|
||||
- check_dirty_state
|
||||
- remove_clone_directory
|
||||
- __init__
|
||||
## workflows
|
||||
- change git behavior
|
||||
read: __init__.py, clone.py, git_operations.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,23 @@
|
||||
# apps/api/src/services/instance (index)
|
||||
dir: apps/api/src/services/instance
|
||||
|
||||
## role
|
||||
Provides infrastructure for managing tool instance lifecycle events, health monitoring, and asynchronous communication within the API service.
|
||||
## parent
|
||||
index: apps/api/src/services/.pi-map.index.md
|
||||
map: apps/api/src/services/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- event_bus.py
|
||||
- health_monitor.py
|
||||
- lifecycle_hooks.py
|
||||
## links
|
||||
index: apps/api/src/services/instance/.pi-map.index.md
|
||||
map: apps/api/src/services/instance/.pi-map.md
|
||||
## workflows
|
||||
- change instance behavior
|
||||
read: __init__.py, event_bus.py, health_monitor.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,30 @@
|
||||
# apps/api/src/services/instance
|
||||
dir: apps/api/src/services/instance
|
||||
|
||||
index: apps/api/src/services/instance/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Provides infrastructure for managing tool instance lifecycle events, health monitoring, and asynchronous communication within the API service.
|
||||
## files
|
||||
- __init__.py | Exports public API for instance lifecycle services module | dep: src.services.instance.event_bus, src.services.instance.health_monitor, src.services.instance.lifecycle_hooks
|
||||
- event_bus.py | Implements a singleton in-memory typed event bus with publish/subscribe pattern for instance lifecycle and health events, supporting both sync and async callbacks with exception isolation. | exp: class:InstanceEventBus, method:__init__(self) → None, method:__new__(cls) → "InstanceEventBus", call:super().__new__, method:_reset_for_testing(self) → None, call:self._subscribers.clear, method:subscribe(self, event_type: str, callback: EventCallback) → Callable[[], None], call:str, call:uuid.uuid4, call:self._subscribers[event_type].append, call:self.unsubscribe, method:unsubscribe(self, event_type: str, callback_id: str) → None, method:unsubscribe_all(self, event_type: str) → None, call:self._subscribers.pop, method:publish(self, event_type: str, payload: InstanceEventPayload) → None, call:callbacks.extend, call:self._subscribers.get, call:inspect.iscoroutinefunction, call:callback, call:payload.get, call:logger.exception | dep: asyncio, inspect, logging, uuid, collections.abc, typing
|
||||
- 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.
|
||||
## tags
|
||||
call:self., instance, src, services, event, health, call:logger.exception, check
|
||||
## symbols
|
||||
- InstanceEventBus
|
||||
- HealthSnapshot
|
||||
- HealthMonitor
|
||||
- __init__
|
||||
- __new__
|
||||
- _reset_for_testing
|
||||
- subscribe
|
||||
- unsubscribe
|
||||
## workflows
|
||||
- change instance behavior
|
||||
read: __init__.py, event_bus.py, health_monitor.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,28 @@
|
||||
# apps/api/src/services/shared (index)
|
||||
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.
|
||||
## parent
|
||||
index: apps/api/src/services/.pi-map.index.md
|
||||
map: apps/api/src/services/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- correlation.py
|
||||
- file_service.py
|
||||
- notification_service.py
|
||||
- permission_fixer.py
|
||||
- readiness_probe.py
|
||||
- ssh_keys.py
|
||||
- tunnel.py
|
||||
- workspace_manager.py
|
||||
## links
|
||||
index: apps/api/src/services/shared/.pi-map.index.md
|
||||
map: apps/api/src/services/shared/.pi-map.md
|
||||
## workflows
|
||||
- change shared behavior
|
||||
read: __init__.py, correlation.py, file_service.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,35 @@
|
||||
# apps/api/src/services/shared
|
||||
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.
|
||||
## 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
|
||||
- file_service.py | Provides safe file operations (list, read, write) scoped within a workspace directory with path traversal protection. | exp: class:FileEntry, class:FileService, method:list_directory(self, workspace: Workspace, relative_path) → list[FileEntry], call:os.path.join, call:os.path.normpath, call:abs_path.startswith, call:os.path.exists, call:sorted, call:os.listdir, call:os.path.isdir, call:os.path.getsize, call:os.path.isfile, call:entries.append, call:FileEntry, call:rel.replace, call:entries.sort, call:e.name.lower, raise:ValueError, method:read_file(self, workspace: Workspace, relative_path: str) → str, call:self._resolve_path, call:os.path.isfile, call:open, call:f.read, raise:FileNotFoundError, raise:ValueError, method:write_file(self, workspace: Workspace, relative_path: str, content: str) → None, call:self._resolve_path, call:os.makedirs, call:os.path.dirname, call:open, call:f.write, call:logger.info, method:_resolve_path(self, workspace: Workspace, relative_path: str) → str, call:os.path.normpath, call:os.path.join, call:abs_path.startswith, raise:ValueError | dep: logging, os, dataclasses, src.models, src.models.Workspace
|
||||
- notification_service.py | Provides an async singleton service for creating, listing, reading, and dismissing user-owned notifications with strict ownership isolation. | exp: class:NotificationService, method:create_notification(self, session: AsyncSession, user_id: uuid.UUID, category: str, severity: str, title: str, message, source_type, source_id, metadata) → Notification, call:Notification, call:session.add, call:session.commit, call:session.refresh, method:list_notifications(self, session: AsyncSession, user_id: uuid.UUID, limit, offset, unread_only, mute_categories) → tuple[list[Notification], int], call:Notification.dismissed_at.is_, call:where_clauses.append, call:Notification.read_at.is_, call:Notification.category.not_in, call:select(func.count()).select_from(Notification).where, call:func.count, call:session.execute, call:total_result.scalar_one, call:select(Notification) .where(*where_clauses) .order_by(Notification.created_at.desc()) .limit(limit) .offset, call:Notification.created_at.desc, call:list, call:items_result.scalars().all, method:get_unread_count(self, session: AsyncSession, user_id: uuid.UUID) → int, call:select(func.count()) .select_from(Notification) .where, call:func.count, call:Notification.read_at.is_, call:Notification.dismissed_at.is_, call:session.execute, call:result.scalar_one, method:mark_read(self, session: AsyncSession, notification_id: uuid.UUID, user_id: uuid.UUID) → Notification, call:self._get_owned_notification, call:datetime.now, call:session.commit, call:session.refresh, method:mark_all_read(self, session: AsyncSession, user_id: uuid.UUID) → int, call:update(Notification) .where( Notification.user_id == user_id, Notification.read_at.is_(None), Notification.dismissed_at.is_(None), ) .values, call:Notification.read_at.is_, call:Notification.dismissed_at.is_, call:datetime.now, call:session.execute, call:session.commit, method:dismiss_all(self, session: AsyncSession, user_id: uuid.UUID) → int, call:update(Notification) .where( Notification.user_id == user_id, Notification.dismissed_at.is_(None), ) .values, call:Notification.dismissed_at.is_, call:datetime.now, call:session.execute, call:session.commit, method:dismiss(self, session: AsyncSession, notification_id: uuid.UUID, user_id: uuid.UUID) → None, call:self._get_owned_notification, call:datetime.now, call:session.commit, method:_get_owned_notification(self, session: AsyncSession, notification_id: uuid.UUID, user_id: uuid.UUID) → Notification, call:session.get, raise:ValueError | dep: uuid, datetime, typing, sqlalchemy, sqlalchemy.engine, sqlalchemy.ext.asyncio, src.models, src.models.Notification
|
||||
- permission_fixer.py | Applies mount and SSH permission policies inside running Docker containers by executing chown/chmod commands via docker exec as root. | exp: class:PermissionFixError, func:apply_mount_permissions(container_id: str, mounts: list[dict], timeout) → list[dict[str, Any]], call:mount.get, call:logger.debug, call:results.append, call:_run_in_container, call:str, call:logger.warning, func:_exec_and_log(container_id: str, command: list[str], timeout: int, description: str) → str, call:logger.debug, call:" ".join, call:subprocess.run, call:result.stdout.strip, call:result.stderr.strip, raise:PermissionFixError, func:apply_ssh_permissions(container_id: str, ssh_target: str, container_user: str, timeout) → dict[str, Any], call:_exec_and_log, call:logger.info, call:str, call:logger.warning, func:_run_in_container(container_id: str, command: list[str], timeout: int) → None, call:subprocess.run, raise:PermissionFixError, func:check_root_user_available(container_id: str, timeout) → bool, call:_run_in_container | dep: logging, subprocess, typing
|
||||
- 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
|
||||
## 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.
|
||||
## tags
|
||||
error, get, key, call:self., src, call:ssh, at.is, call:session.execute
|
||||
## symbols
|
||||
- CorrelationIdMiddleware
|
||||
- FileEntry
|
||||
- FileService
|
||||
- NotificationService
|
||||
- PermissionFixError
|
||||
- SyncResult
|
||||
- WorkspaceHasInstancesError
|
||||
- WorkspaceManager
|
||||
## workflows
|
||||
- change shared behavior
|
||||
read: __init__.py, correlation.py, file_service.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,22 @@
|
||||
# apps/api/src/services/terminal (index)
|
||||
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.
|
||||
## parent
|
||||
index: apps/api/src/services/.pi-map.index.md
|
||||
map: apps/api/src/services/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- terminal_manager.py
|
||||
- terminal_session.py
|
||||
## links
|
||||
index: apps/api/src/services/terminal/.pi-map.index.md
|
||||
map: apps/api/src/services/terminal/.pi-map.md
|
||||
## workflows
|
||||
- change terminal behavior
|
||||
read: __init__.py, terminal_manager.py, terminal_session.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,29 @@
|
||||
# apps/api/src/services/terminal
|
||||
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.
|
||||
## 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.
|
||||
## tags
|
||||
call:self., session, call:logger.debug, idle, output, terminal, check, task
|
||||
## symbols
|
||||
- MaxSessionsExceededError
|
||||
- TerminalManager
|
||||
- TerminalSession
|
||||
- __init__
|
||||
- _start_idle_check
|
||||
- _idle_check_loop
|
||||
- _cleanup_idle_sessions
|
||||
- _insert_db_session_row
|
||||
## workflows
|
||||
- change terminal behavior
|
||||
read: __init__.py, terminal_manager.py, terminal_session.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,20 @@
|
||||
# apps/api/src/services/tool (index)
|
||||
dir: apps/api/src/services/tool
|
||||
|
||||
## role
|
||||
Orchestrates Docker container lifecycle for tool instances with git repository mounting, configuration validation, and SSH tunnel management.
|
||||
## parent
|
||||
index: apps/api/src/services/.pi-map.index.md
|
||||
map: apps/api/src/services/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- instance_service.py
|
||||
## links
|
||||
index: apps/api/src/services/tool/.pi-map.index.md
|
||||
map: apps/api/src/services/tool/.pi-map.md
|
||||
## workflows
|
||||
- change tool behavior
|
||||
read: instance_service.py
|
||||
## dirty
|
||||
-
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,24 @@
|
||||
# apps/api/src/utils (index)
|
||||
dir: apps/api/src/utils
|
||||
|
||||
## role
|
||||
Provides Git repository interaction utilities for the API layer, abstracting subprocess-based git operations into reusable Python modules.
|
||||
## parent
|
||||
index: apps/api/src/.pi-map.index.md
|
||||
map: apps/api/src/.pi-map.md
|
||||
## children
|
||||
-
|
||||
## files
|
||||
- __init__.py
|
||||
- git_control.py
|
||||
- git_files.py
|
||||
- git_history.py
|
||||
- git_url_parser.py
|
||||
## links
|
||||
index: apps/api/src/utils/.pi-map.index.md
|
||||
map: apps/api/src/utils/.pi-map.md
|
||||
## workflows
|
||||
- change utils behavior
|
||||
read: __init__.py, git_control.py, git_files.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,31 @@
|
||||
# apps/api/src/utils
|
||||
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.
|
||||
## 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
|
||||
- git_files.py | Provides utilities for browsing and manipulating Git repository contents including file trees, branches, file contents, and commits via subprocess git commands. | exp: class:FileTreeEntry, class:BranchInfo, class:FileContent, func:_run_git_command(repo_path: str, *args: str) → str, call:subprocess.run, call:stderr.lower, call:logger.warning, raise:RuntimeError, func:list_tree(repo_path: str, branch, path) → list[FileTreeEntry], call:_run_git_command, call:logger.warning, call:logger.error, call:str(e).lower, call:output.strip().split, call:line.split, call:len, call:meta.split, call:int, call:_get_last_commit_for_path, call:entries.append, call:FileTreeEntry, func:_get_last_commit_for_path(repo_path: str, branch: str, path: str) → dict[str, Any] | None, call:_run_git_command, call:output.strip().split, call:len, func:get_file_content(repo_path: str, branch: str, path: str) → FileContent, call:_run_git_command, call:int, call:size_output.strip, call:_is_binary_file, call:_detect_language, call:_get_last_commit_for_path, call:FileContent, raise:FileNotFoundError, func:_is_binary_file(repo_path: str, branch: str, path: str) → bool, call:subprocess.run, raise:RuntimeError, func:_detect_language(path: str) → str | None, call:Path(path).suffix.lower, call:language_map.get, func:list_branches(repo_path: str) → tuple[list[BranchInfo], str], call:_run_git_command, call:logger.error, call:str, call:r.strip, call:remote_output.strip().split, call:set, call:output.strip().split, call:line.strip, call:branch_name.split, call:branch_name.startswith, call:len, call:any, call:head_output.strip, call:_get_last_commit_for_path, call:branches.append, call:BranchInfo, func:commit_file(repo_path: str, branch: str, path: str, content: str, commit_message: str, author_name: str, author_email: str) → str, call:tempfile.TemporaryDirectory, call:os.path.join, call:os.makedirs, call:os.path.dirname, call:open, call:f.write, call:_run_git_command( worktree_path, "rev-parse", "HEAD", ).strip | dep: logging, subprocess, dataclasses, pathlib, typing, tempfile, os
|
||||
- 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.
|
||||
## tags
|
||||
call:, git, run, command, get, url, commit, call:len
|
||||
## symbols
|
||||
- GitStatus
|
||||
- FileTreeEntry
|
||||
- BranchInfo
|
||||
- FileContent
|
||||
- Commit
|
||||
- FileChange
|
||||
- CommitDetail
|
||||
- _run_git_command
|
||||
## workflows
|
||||
- change utils behavior
|
||||
read: __init__.py, git_control.py, git_files.py
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,36 @@
|
||||
# apps/api/tests (index)
|
||||
dir: apps/api/tests
|
||||
|
||||
## role
|
||||
Shared testing infrastructure and fixtures for the FastAPI API application
|
||||
## parent
|
||||
index: apps/api/.pi-map.index.md
|
||||
map: apps/api/.pi-map.md
|
||||
## children
|
||||
- apps/api/tests/api
|
||||
index: apps/api/tests/api/.pi-map.index.md
|
||||
map: apps/api/tests/api/.pi-map.md
|
||||
- apps/api/tests/integration
|
||||
index: apps/api/tests/integration/.pi-map.index.md
|
||||
map: apps/api/tests/integration/.pi-map.md
|
||||
- apps/api/tests/services
|
||||
index: apps/api/tests/services/.pi-map.index.md
|
||||
map: apps/api/tests/services/.pi-map.md
|
||||
- apps/api/tests/system
|
||||
index: apps/api/tests/system/.pi-map.index.md
|
||||
map: apps/api/tests/system/.pi-map.md
|
||||
- apps/api/tests/unit
|
||||
index: apps/api/tests/unit/.pi-map.index.md
|
||||
map: apps/api/tests/unit/.pi-map.md
|
||||
## files
|
||||
- conftest.py
|
||||
## links
|
||||
index: apps/api/tests/.pi-map.index.md
|
||||
map: apps/api/tests/.pi-map.md
|
||||
## workflows
|
||||
- change tests behavior
|
||||
read: conftest.py
|
||||
- explore tests subdirectories
|
||||
index: apps/api/tests/api/.pi-map.index.md, apps/api/tests/integration/.pi-map.index.md, apps/api/tests/services/.pi-map.index.md
|
||||
## dirty
|
||||
-
|
||||
@@ -0,0 +1,29 @@
|
||||
# apps/api/tests
|
||||
dir: apps/api/tests
|
||||
|
||||
index: apps/api/tests/.pi-map.index.md
|
||||
|
||||
## role
|
||||
Shared testing infrastructure and fixtures for the FastAPI API application
|
||||
## 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
|
||||
## arch
|
||||
Pytest fixture-based dependency injection pattern with async SQLite test database, authenticated HTTP client factories, and modular test data setup utilities
|
||||
## tags
|
||||
call:app.dependency, call:create, overrides.get, call:override, fn, call:gen.asend, call:gen.aclose, session
|
||||
## symbols
|
||||
- test_client
|
||||
- init_db
|
||||
- override_get_db_session
|
||||
- db_session
|
||||
- authenticated_client
|
||||
- create_test_user
|
||||
- test_project_and_repo
|
||||
- get_user_id
|
||||
## workflows
|
||||
- change tests behavior
|
||||
read: conftest.py
|
||||
- explore tests subdirectories
|
||||
index: apps/api/tests/api/.pi-map.index.md, apps/api/tests/integration/.pi-map.index.md, apps/api/tests/services/.pi-map.index.md
|
||||
## dirty
|
||||
-
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user