/** * workspace-migration.ts — Phase 3: workspace replacement for empty projects. * * When a user attaches a real backend (git, sharepoint, etc.) to a project * that previously used a local temp workspace, we need to: * 1. Mount the new mount to a staging path * 2. Detect whether the target is blank (no user files) * 3. Copy workspace files to the right destination * 4. Commit if git-backed * 5. Swap mounts: unmount old workspace + staging, mount new mount as workspace * 6. Emit resource_status: active * * On failure at any step, rollback: unmount staging, delete staging dir, emit error. * * ── Why everything here is async ───────────────────────────────────────── * * This module is the worst case for the issue #454 outage class: it copies a * whole tree **from one mount to another** (the old workspace to the newly * mounted backend), removes trees recursively, and shells out to git — all on * paths that are network filesystems by construction. Done synchronously that * parks the runner's single event loop for the entire migration, and a wedged * rclone mount parks it forever; a hang is not an error, so the `try/catch` * rollback below would never fire. * * Every filesystem call is therefore awaited and deadline-bounded, and every * git call carries an explicit timeout. That holds even though nothing wires * this entry point up yet — the cost of getting it right now is a rewrite, the * cost of getting it right after someone calls it is an outage. */ import type { ConnectorManager } from "@skaile/workspaces/connectors"; import type { ResourceDeclaration, ResourceMigration } from "@skaile/workspaces/types"; type ReplaceWorkspaceMigration = Extract; /** * Replace the current workspace mount with a new mount backend. * * Steps: * 1. Mount new mount to ../.staging (relative to workspace) * 2. Check if staging is blank (no non-hidden files) * 3. Copy workspace files — to root if blank, into named subfolder if non-blank * 4. Git add+commit if driver is 'git' * 5. Unmount old workspace and staging * 6. Mount new mount as workspace * 7. Emit resource_status: active * * On any error: rollback (unmount staging, clean up staging dir, emit error status). * @docLink packages/runner/dev-guide#flow-execution-turn-based-model */ export declare function handleWorkspaceReplacement(resource: ResourceDeclaration, migration: ReplaceWorkspaceMigration, connectorManager: ConnectorManager, sendEvent: (event: Record) => void, workspaceDir: string): Promise; /** * Returns true if the directory has no non-hidden files or directories. * Hidden entries (starting with '.') are ignored — e.g. .git, .DS_Store. * @param dir - Directory to inspect. May be a network mount. * @throws {FsDeadlineError} when the directory does not answer in time. * @docLink packages/runner/dev-guide#flow-execution-turn-based-model */ export declare function isEffectivelyEmpty(dir: string): Promise; /** * Recursively copy src into dest, skipping hidden entries (starting with '.'). * * Hand-rolled rather than `fs.cp(..., { recursive: true, filter })` because the * skip rule is "hidden at any level", and a single deadline around a whole-tree * `cp` would be all-or-nothing: one slow subtree would abort a copy that had * already moved gigabytes. Per-entry deadlines keep the failure local and the * progress made. * * @param src - Source directory (may be a network mount). * @param dest - Destination directory; must already exist. * @throws {FsDeadlineError} when any single entry misses its deadline. * @docLink packages/runner/dev-guide#flow-execution-turn-based-model */ export declare function copyDirectory(src: string, dest: string): Promise; /** * Run `git add -A` and `git commit` in repoDir. Skips the commit if nothing * is staged (i.e. the workspace was already empty or all files were hidden). * * `repoDir` is a freshly mounted backend, so each git call carries an explicit * timeout and is killed with `SIGKILL` — `SIGTERM` is not delivered to a * `D`-state process on a dead FUSE connection. * * @param repoDir - Git repository root to stage and commit in. * @param message - Commit message. * @docLink packages/runner/dev-guide#flow-execution-turn-based-model */ export declare function gitAddAndCommit(repoDir: string, message: string): Promise; export {}; //# sourceMappingURL=workspace-migration.d.ts.map