feat: add workspace sources from files panel (#1900)

* feat: add workspace sources from files panel

* fix: preserve worktree identity during recovery

* feat: unify workspace source actions

* fix: validate recovered workspace repositories

* fix: harden workspace source filesystem boundaries

* test: split workspace repository chip coverage

* fix: restrict repository rescan recovery paths

* fix: stabilize workspace source CI checks

* test: canonicalize workspace source paths

* test: align workspace source container paths

* fix: populate direct workspace repository names

* test: preserve git fixture rewrites across restarts

* test: isolate backend git fixture config

* fix: resume remote workspace executions before creation

* fix: preserve ssh agent identity during resume

* fix: preserve SSH workspace across backend restart

* fix: simplify workspace actions trigger

* fix: refine add workspace repositories UX

* docs: narrow workspace source UX updates

* fix: avoid phantom turn on session resume

* test(web): normalize workspace source request headers

* feat(web): streamline workspace source picker

* docs: remove trailing spaces from workspace source plan

* fix: prevent resume status from creating phantom turns

* fix(web): stabilize workspace source attachment

* refactor(web): extract workspace source store contract

* fix: avoid phantom turns on idle agent resume

* fix: address backend static analysis findings

* fix: preserve agentctl readiness status value

* fix: preserve resume messages without active turns

* fix: resume agents from promoted workspace root

* chore: merge origin/main into feature/add-new-repo-folder-d97

* feat(web): explain workspace source consequences

* test(websocket): count session activity subscription
This commit is contained in:
Carlos Florêncio
2026-07-25 21:29:53 +01:00
committed by GitHub
parent dc38aaf0d0
commit bc218dfbbe
215 changed files with 17461 additions and 1697 deletions
@@ -136,6 +136,16 @@ type TaskRepoRepository interface {
GetPrimaryTaskRepository(ctx context.Context, taskID string) (*models.TaskRepository, error)
}
// TaskWorkspaceFolderRepository handles canonical non-Git folder attachments.
// It is intentionally separate from TaskRepoRepository to preserve existing
// repository payload and Git-consumer contracts.
type TaskWorkspaceFolderRepository interface {
ListTaskWorkspaceFolders(ctx context.Context, taskID string) ([]*models.TaskWorkspaceFolder, error)
ListTaskWorkspaceFoldersByTaskIDs(ctx context.Context, taskIDs []string) (map[string][]*models.TaskWorkspaceFolder, error)
CreateWorkspaceSourceBatch(ctx context.Context, batch *models.WorkspaceSourceBatch) error
CompensateWorkspaceSourceBatch(ctx context.Context, batch *models.WorkspaceSourceBatch) error
}
// WorkflowRepository handles workflow CRUD.
type WorkflowRepository interface {
CreateWorkflow(ctx context.Context, workflow *models.Workflow) error
@@ -282,6 +292,15 @@ type RepositoryEntityRepository interface {
GetRepositoryByLocalPath(ctx context.Context, workspaceID, localPath string) (*models.Repository, error)
}
// RepositoryCleanupRepository performs guarded deletion of repositories
// created during workspace-source attachment rollback.
type RepositoryCleanupRepository interface {
// DeleteRepositoryIfUnreferenced soft-deletes a repository only when no
// task_repositories row currently adopts it. The predicate is part of the
// mutation so rollback cleanup cannot delete a repository another task won.
DeleteRepositoryIfUnreferenced(ctx context.Context, id string) (bool, error)
}
// ExecutorRepository handles executor CRUD, executor profiles, and running state.
type ExecutorRepository interface {
CreateExecutor(ctx context.Context, executor *models.Executor) error