@agimon-ai/po-git 0.0.0-alpha.44 → 0.0.0-alpha.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktreeOperations-C1ygq-Na.cjs","names":["fs","path","fs","randomUUID","path","fs","createHash","os","path","poHomeDirectory","fs","isDeepStrictEqual","randomUUID","fs","path","setTimeout","path","load","fs","require","randomUUID"],"sources":["../src/services/gitCli/index.ts","../src/constants/git.ts","../src/services/errors/index.ts","../src/services/atomicJson/index.ts","../src/services/repositoryIdentity/index.ts","../src/services/paths/index.ts","../src/services/worktreeEvents/index.ts","../src/services/worktreeNaming/index.ts","../src/services/worktreeRegistry/index.ts","../src/services/worktreeOperations/index.ts"],"sourcesContent":["import { execFile } from 'node:child_process';\nimport fs from 'node:fs/promises';\n\nimport type { GitBranches, GitLocalBranch, GitRemoteBranch } from '../../types/gitSessions';\nimport type { WorktreeGit } from '../../types/worktreeRegistry';\n\n/**\n * Git, as this package needs it.\n *\n * The timeouts are not uniform because the operations are not comparable. A\n * read answers in milliseconds; `worktree add` copies an entire checkout and\n * `worktree remove` deletes one, both bounded by the filesystem rather than by\n * git, and both minutes rather than seconds on a large repository or on\n * Windows. A single timeout would either fail honest work or hang on a wedged\n * one.\n */\nexport const READ_TIMEOUT_MS = 30_000;\nconst ADD_TIMEOUT_MS = 300_000;\nconst REMOVE_TIMEOUT_MS = 300_000;\nconst PRUNE_TIMEOUT_MS = 15_000;\n/** fetch and push: bounded by the network, so long enough for a slow link, short enough to notice a dead one. */\nexport const NETWORK_TIMEOUT_MS = 120_000;\n/** A rebase replays commits locally; a large branch on a slow disk takes minutes, never hours. */\nexport const REBASE_TIMEOUT_MS = 300_000;\nconst MAX_OUTPUT_BYTES = 1_000_000;\n/** Enough for any branch picker; a repository with more refs lists its most recent ones. */\nconst MAX_LISTED_REFS = 2_000;\nconst LOCAL_PREFIX = 'refs/heads/';\nconst REMOTE_PREFIX = 'refs/remotes/';\nconst HEAD_SUFFIX = '/HEAD';\n\nexport interface GitResult {\n code: number;\n stdout: string;\n stderr: string;\n /** The timeout killed git. */\n timedOut: boolean;\n /** Output passed maxBuffer and git was killed; stdout is truncated. */\n overflow: boolean;\n}\n\nexport interface RunGitOptions {\n timeout: number;\n /** The whole environment for this one child. Defaults to the hub's own. */\n env?: NodeJS.ProcessEnv;\n maxBuffer?: number;\n}\n\n/**\n * Runs git and reports the outcome without ever throwing on a non-zero exit.\n *\n * LC_ALL is pinned because callers decide what to do by matching git's own\n * wording, and a translated message would silently turn a recognised\n * condition into an unrecognised failure.\n *\n * `env` replaces the environment for this child only. That is how remote auth\n * reaches fetch and push without ever touching the hub's own process.env,\n * which every session started afterwards would inherit.\n */\nexport function runGit(cwd: string, args: readonly string[], options: RunGitOptions): Promise<GitResult> {\n return new Promise((resolve) => {\n execFile(\n 'git',\n [...args],\n {\n cwd,\n timeout: options.timeout,\n maxBuffer: options.maxBuffer ?? MAX_OUTPUT_BYTES,\n env: { ...(options.env ?? process.env), LC_ALL: 'C' },\n },\n (error, stdout, stderr) => {\n const failure = error as (NodeJS.ErrnoException & { killed?: boolean; signal?: string | null }) | null;\n const code = failure && typeof failure.code === 'number' ? failure.code : failure ? 1 : 0;\n resolve({\n code,\n stdout: String(stdout),\n stderr: String(stderr),\n timedOut: failure?.killed === true && failure.code !== 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER',\n overflow: failure?.code === 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER',\n });\n },\n );\n });\n}\n\nfunction git(cwd: string, args: readonly string[], timeout: number): Promise<GitResult> {\n return runGit(cwd, args, { timeout });\n}\n\n/**\n * The message a failed git call is allowed to surface.\n *\n * Raw stderr never travels: it can carry a remote URL with a token in it, and\n * this text ends up in a tool result the model reads and may repeat.\n */\nfunction failure(operation: string, result: GitResult): Error {\n return new Error(\n `git ${operation} failed (exit ${String(result.code)}, ${String(result.stderr.length)} bytes of stderr)`,\n );\n}\n\n/** Git's own words for \"that worktree is not there any more\". */\nfunction missingWorktree(stderr: string): boolean {\n const normalized = stderr.toLowerCase();\n return normalized.includes('is not a working tree') || normalized.includes('cannot remove working tree');\n}\n\nexport function createWorktreeGit(): WorktreeGit {\n const prune = async (repositoryRoot: string): Promise<void> => {\n await git(repositoryRoot, ['worktree', 'prune'], PRUNE_TIMEOUT_MS);\n };\n\n return {\n async addWorktree({ repositoryRoot, path, branch, baseRef }) {\n const result = await git(repositoryRoot, ['worktree', 'add', '-b', branch, path, baseRef], ADD_TIMEOUT_MS);\n if (result.code !== 0) throw failure('worktree add', result);\n },\n\n async addExistingWorktree({ repositoryRoot, path, branch, remote }) {\n const args =\n remote === undefined\n ? ['worktree', 'add', path, branch]\n : ['worktree', 'add', '--track', '-b', branch, path, `${remote}/${branch}`];\n const result = await git(repositoryRoot, args, ADD_TIMEOUT_MS);\n if (result.code !== 0) throw failure('worktree add', result);\n },\n\n async listBranches(repositoryRoot): Promise<GitBranches> {\n const refs = await git(\n repositoryRoot,\n [\n 'for-each-ref',\n '--sort=-committerdate',\n `--count=${String(MAX_LISTED_REFS)}`,\n '--format=%(refname)%09%(worktreepath)%09%(symref)',\n 'refs/heads',\n 'refs/remotes',\n ],\n READ_TIMEOUT_MS,\n );\n if (refs.code !== 0) throw failure('for-each-ref', refs);\n const local: GitLocalBranch[] = [];\n const remotes: GitRemoteBranch[] = [];\n for (const line of refs.stdout.split('\\n')) {\n const [ref = '', worktreePath = '', symref = ''] = line.split('\\t');\n if (ref === '' || symref !== '') continue;\n if (ref.startsWith(LOCAL_PREFIX)) {\n const name = ref.slice(LOCAL_PREFIX.length);\n local.push(worktreePath === '' ? { name } : { name, checkedOutAt: worktreePath });\n } else if (ref.startsWith(REMOTE_PREFIX) && !ref.endsWith(HEAD_SUFFIX)) {\n const rest = ref.slice(REMOTE_PREFIX.length);\n const separator = rest.indexOf('/');\n if (separator > 0) remotes.push({ remote: rest.slice(0, separator), name: rest.slice(separator + 1) });\n }\n }\n const localNames = new Set(local.map((branch) => branch.name));\n const head = await git(repositoryRoot, ['symbolic-ref', '--quiet', '--short', 'HEAD'], READ_TIMEOUT_MS);\n const current = head.code === 0 && head.stdout.trim() !== '' ? head.stdout.trim() : undefined;\n const origin = await git(\n repositoryRoot,\n ['symbolic-ref', '--quiet', '--short', 'refs/remotes/origin/HEAD'],\n READ_TIMEOUT_MS,\n );\n const defaultBase = origin.code === 0 && origin.stdout.trim() !== '' ? origin.stdout.trim() : current;\n return {\n ...(current === undefined ? {} : { current }),\n ...(defaultBase === undefined ? {} : { defaultBase }),\n local,\n remote: remotes.filter((branch) => !localNames.has(branch.name)),\n };\n },\n\n async removeWorktree({ repositoryRoot, path, force }) {\n const args = ['worktree', 'remove', ...(force ? ['--force'] : []), path];\n const result = await git(repositoryRoot, args, REMOVE_TIMEOUT_MS);\n if (result.code === 0) return;\n // A directory deleted behind git's back leaves an administrative entry\n // that makes a later `worktree add` at the same path refuse. Treating\n // \"already gone\" as success and pruning is what keeps that path reusable,\n // and it makes remove idempotent for a caller retrying after a crash.\n if (\n missingWorktree(result.stderr) &&\n !(await fs.access(path).then(\n () => true,\n () => false,\n ))\n ) {\n await prune(repositoryRoot);\n return;\n }\n throw failure('worktree remove', result);\n },\n\n async deleteBranch({ repositoryRoot, branch }) {\n // -d, never -D: git refuses a branch that still holds unmerged commits,\n // and that refusal is the whole safety property. A rollback that could\n // throw away work someone committed in the worktree is worse than a\n // branch left behind.\n const result = await git(repositoryRoot, ['branch', '-d', branch], READ_TIMEOUT_MS);\n return result.code === 0;\n },\n pruneWorktrees: prune,\n\n async listWorktreePaths(repositoryRoot) {\n const result = await git(repositoryRoot, ['worktree', 'list', '--porcelain'], READ_TIMEOUT_MS);\n if (result.code !== 0) return [];\n return result.stdout\n .split('\\n')\n .filter((line) => line.startsWith('worktree '))\n .map((line) => line.slice('worktree '.length).trim())\n .filter((line) => line !== '');\n },\n\n async dirtyFiles(path) {\n const result = await git(path, ['status', '--porcelain'], READ_TIMEOUT_MS);\n if (result.code !== 0) return [];\n return result.stdout\n .split('\\n')\n .map((line) => line.slice(3).trim())\n .filter((line) => line !== '');\n },\n\n async repositoryRoot(cwd) {\n const result = await git(cwd, ['rev-parse', '--show-toplevel'], READ_TIMEOUT_MS);\n if (result.code !== 0) return undefined;\n const root = result.stdout.trim();\n return root === '' ? undefined : root;\n },\n\n async currentBranch(cwd) {\n const result = await git(cwd, ['rev-parse', '--abbrev-ref', 'HEAD'], READ_TIMEOUT_MS);\n if (result.code !== 0) return undefined;\n const branch = result.stdout.trim();\n return branch === '' ? undefined : branch;\n },\n\n async remoteBaseRef(cwd) {\n const upstream = await git(\n cwd,\n ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{upstream}'],\n READ_TIMEOUT_MS,\n );\n if (upstream.code === 0) {\n const branch = upstream.stdout.trim();\n if (branch !== '') return branch;\n }\n const origin = await git(\n cwd,\n ['symbolic-ref', '--quiet', '--short', 'refs/remotes/origin/HEAD'],\n READ_TIMEOUT_MS,\n );\n if (origin.code === 0) {\n const branch = origin.stdout.trim();\n if (branch !== '') return branch;\n }\n const defaults = await git(cwd, ['for-each-ref', '--format=%(symref:short)', 'refs/remotes'], READ_TIMEOUT_MS);\n if (defaults.code !== 0) return undefined;\n return defaults.stdout\n .split('\\n')\n .map((line) => line.trim())\n .find((line) => line !== '');\n },\n\n async mergeBranch({ repositoryRoot, branch, message }) {\n // --no-ff so the worktree's work stays identifiable as a unit after the\n // fact. A fast-forward would erase the fact that it was ever separate,\n // which is the one thing worth keeping about a worktree.\n const args = ['merge', '--no-ff', ...(message === undefined ? [] : ['-m', message]), branch];\n const result = await git(repositoryRoot, args, READ_TIMEOUT_MS);\n if (result.code === 0) return;\n // A conflicted merge leaves the parent mid-merge, which is a state the\n // person has to resolve; aborting for them would throw away the conflict\n // markers they need to see.\n throw failure('merge', result);\n },\n };\n}\n","export const COMMAND_NAME = 'po-git';\nexport const COMMAND_DESCRIPTION = 'Show git worktrees owned by this session';\n/** The package API base path; the cockpit mounts it at /api/workspaces/<id>/plugins/git. */\nexport const GIT_API_BASE_PATH = 'git';\n/** Workspace-mounted routes behind the new-session dialog. */\nexport const GIT_BRANCHES_PATH = '/branches';\nexport const GIT_SESSIONS_PATH = '/sessions';\n/** Workspace-mounted: that workspace's remote auth for manual pull, push and rebase. */\nexport const GIT_AUTH_PATH = '/auth';\n/** Session-mounted: the session's change against its base, and one file's hunks. */\nexport const GIT_REVIEW_PATH = '/review';\nexport const GIT_REVIEW_FILE_PATH = '/review/file';\n/** Repository file, relative to the checkout root, whose `setup` commands run in every new worktree. */\nexport const WORKTREE_CONFIG_FILE = '.po/worktree.yaml';\n/**\n * po-runner's session command, so setup runs as a runner of the worktree session and its log\n * shows in Runners. Mirrors po-runner's `runnerLaunchLine`; the command follows the separator.\n */\nexport const WORKTREE_SETUP_LAUNCH = '/runners start name=worktree-setup --';\n","/**\n * Expected failures, kept private to this package.\n *\n * `@agimon-ai/po-core` does not export `invalidRequest` or\n * an expected-error base, so this mirrors po-team's shape rather than\n * reaching across a layer boundary for it. The duplication is deliberate and\n * small; a shared helper would be the better answer only once a third package\n * needs one.\n */\n\nexport type PoGitErrorCode =\n | 'invalid_request'\n | 'not_a_repository'\n | 'worktree_exists'\n | 'worktree_not_found'\n | 'worktree_not_owned'\n | 'worktree_peer_unavailable'\n | 'worktree_dirty'\n | 'hub_unavailable'\n | 'spawn_cancelled'\n | 'registry_write_failed'\n | 'registry_busy'\n | 'task_delivery_failed'\n | 'message_delivery_failed'\n | 'message_too_large'\n | 'git_failed'\n // Remote auth and sync. Each carries its own recovery line; git's stderr is\n // only ever matched, never shown, because it can carry a token in a URL.\n | 'auth_failed'\n | 'host_key_unknown'\n | 'host_key_changed'\n | 'remote_unreachable'\n | 'repository_not_found'\n | 'push_needs_force'\n | 'push_lease_rejected'\n | 'no_upstream'\n | 'no_remote'\n | 'no_base'\n | 'detached_head'\n | 'rebase_in_progress'\n | 'git_timeout';\n\nexport class PoGitExpectedError extends Error {\n constructor(\n readonly code: PoGitErrorCode,\n message: string,\n readonly retryable: boolean,\n readonly recovery: string,\n ) {\n // The recovery line rides in the message because a tool result is read as\n // text: an error the model cannot act on costs a turn to rediscover.\n super(`[${code}] ${message}\\nRecovery: ${recovery}`);\n this.name = 'PoGitExpectedError';\n }\n}\n\n/** Raised when a worktree action needs the canonical hub but it is not injected. */\nexport class HubUnavailableError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'HubUnavailableError';\n }\n}\n\nexport function invalidRequest(message: string, recovery: string): PoGitExpectedError {\n return new PoGitExpectedError('invalid_request', message, false, recovery);\n}\n","import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nconst OWNER_ONLY_FILE = 0o600;\n\n/**\n * Writes JSON so a reader never sees a half-written file.\n *\n * The registry is read by the same process that writes it, and by a later\n * process after a crash. A plain write can be interrupted between the truncate\n * and the last byte, which leaves a file that parses as nothing and loses every\n * record in it. Writing beside the target and renaming makes the swap atomic on\n * the same filesystem, so a reader sees either the old file or the new one.\n */\nexport async function writeJsonAtomic(file: string, value: unknown): Promise<void> {\n const directory = path.dirname(file);\n await fs.mkdir(directory, { recursive: true });\n const temporary = path.join(directory, `.${path.basename(file)}.${randomUUID()}.tmp`);\n await fs.writeFile(temporary, `${JSON.stringify(value, null, 2)}\\n`, { mode: OWNER_ONLY_FILE });\n await fs.rename(temporary, file);\n}\n\n/**\n * Reads JSON, treating every failure as absent.\n *\n * A missing file and an unparseable one mean the same thing to every caller\n * here: there is nothing to act on. Distinguishing them would only offer a\n * choice no caller wants to make.\n */\nexport async function readJson<T>(file: string): Promise<T | undefined> {\n try {\n return JSON.parse(await fs.readFile(file, 'utf8')) as T;\n } catch {\n return undefined;\n }\n}\n","import { createHash } from 'node:crypto';\nimport type { Stats } from 'node:fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nconst ID_LENGTH = 12;\nconst MAX_LABEL_LENGTH = 32;\n\n/**\n * The git directory shared by a repository and all of its worktrees.\n *\n * A normal checkout has a `.git` directory. A linked worktree has a `.git`\n * FILE pointing at `<common>/worktrees/<name>`, whose `commondir` points back\n * at the shared directory. Following that chain is what makes every worktree of\n * one repository agree on the repository's identity, which matters here because\n * the registry is per repository and must be found from inside a worktree too.\n * A session may run in a subdirectory, so the nearest enclosing checkout is used.\n */\nexport async function gitCommonDirectory(directory: string): Promise<string | undefined> {\n let root = path.resolve(directory);\n let marker = path.join(root, '.git');\n let stat: Stats | undefined;\n for (;;) {\n try {\n stat = await fs.stat(marker);\n break;\n } catch {\n const parent = path.dirname(root);\n if (parent === root) return undefined;\n root = parent;\n marker = path.join(root, '.git');\n }\n }\n if (stat.isDirectory()) return marker;\n let pointer: string;\n try {\n pointer = (await fs.readFile(marker, 'utf8')).trim();\n } catch {\n return undefined;\n }\n if (!pointer.startsWith('gitdir:')) return undefined;\n const gitDir = path.resolve(root, pointer.slice('gitdir:'.length).trim());\n try {\n const common = (await fs.readFile(path.join(gitDir, 'commondir'), 'utf8')).trim();\n return path.resolve(gitDir, common);\n } catch {\n // A submodule's .git file has no commondir; its gitdir is already common.\n return gitDir;\n }\n}\n\n/** A directory name that is recognisable to a person and safe on a filesystem. */\nexport function repositoryLabel(root: string): string {\n const label = path\n .basename(root)\n .toLowerCase()\n .replace(/[^a-z0-9]+/gu, '-')\n .replace(/^-+|-+$/gu, '')\n .slice(0, MAX_LABEL_LENGTH);\n return label === '' ? 'repository' : label;\n}\n\n/**\n * A stable id for the repository a directory belongs to.\n *\n * Keyed on the common git directory rather than the given path, so the main\n * checkout and every worktree of it resolve to one id and therefore to one\n * registry. Falling back to the path keeps a non-repository directory usable\n * instead of failing, though nothing here should reach that case.\n */\nexport async function repositoryId(root: string): Promise<string> {\n const common = await gitCommonDirectory(root);\n const token = common === undefined ? `root:${path.resolve(root)}` : `git:${common}`;\n return createHash('sha256').update(token).digest('hex').slice(0, ID_LENGTH);\n}\n\n/** A short, collision-resistant suffix for one worktree directory. */\nexport function shortId(seed: string): string {\n return createHash('sha256').update(seed).digest('hex').slice(0, 8);\n}\n","import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\n\nimport { poHomeDirectory } from '@agimon-ai/po-core/piSettings';\n\nimport { WORKTREE_RECORD_VERSION, type WorktreeRecord } from '../../types/worktreeRegistry';\nimport { readJson, writeJsonAtomic } from '../atomicJson';\nimport { repositoryId } from '../repositoryIdentity';\n\n/**\n * Where this package keeps its own state.\n *\n * Outside the repository on purpose. A worktree directory inside the checkout\n * would be found by every glob the repository's own tooling runs, and would\n * resolve workspace imports against the parent checkout rather than the\n * worktree, so a session there would build the wrong source while appearing to\n * work.\n */\nexport function poGitRoot(homeDir: string = os.homedir()): string {\n return path.join(poHomeDirectory(homeDir), 'git');\n}\n\n/** The directory every worktree for every repository is created under. */\nexport function worktreesRoot(homeDir: string = os.homedir()): string {\n return path.join(poGitRoot(homeDir), 'worktrees');\n}\n\n/**\n * Remote auth for every workspace, one entry per workspace root.\n *\n * Outside every repository, so a token can never be committed, and readable\n * only by the owner. It holds secrets, which no other file here does.\n */\nexport function credentialsFile(homeDir: string = os.homedir()): string {\n return path.join(poGitRoot(homeDir), 'credentials.json');\n}\n/** One registry file per repository, keyed by the shared git directory. */\nexport async function registryFile(repositoryRoot: string, homeDir: string = os.homedir()): Promise<string> {\n const id = await repositoryId(repositoryRoot);\n const root = path.join(poGitRoot(homeDir), 'registry');\n const canonical = path.join(root, id, 'worktrees.json');\n if (\n await fs.access(canonical).then(\n () => true,\n () => false,\n )\n )\n return canonical;\n let names: string[];\n try {\n names = await fs.readdir(root);\n } catch {\n return canonical;\n }\n const legacyFiles: string[] = [];\n for (const entry of names.filter((name) => name.endsWith(`--${id}`)).sort()) {\n const file = path.join(root, entry, 'worktrees.json');\n if (\n await fs.access(file).then(\n () => true,\n () => false,\n )\n )\n legacyFiles.push(file);\n }\n if (legacyFiles.length === 0) return canonical;\n const entries = new Map<string, WorktreeRecord>();\n for (const file of legacyFiles) {\n const legacy = await readJson<{ version?: unknown; entries?: unknown }>(file);\n if (legacy?.version !== WORKTREE_RECORD_VERSION || !Array.isArray(legacy.entries)) continue;\n for (const value of legacy.entries) {\n if (\n typeof value !== 'object' ||\n value === null ||\n !('id' in value) ||\n typeof value.id !== 'string' ||\n value.id === ''\n )\n continue;\n const entry = value as WorktreeRecord;\n const existing = entries.get(entry.id);\n if (existing !== undefined && !isDeepStrictEqual(existing, entry)) {\n throw new Error(`Conflicting legacy worktree registry entries for '${entry.id}'.`);\n }\n entries.set(entry.id, entry);\n }\n }\n const temporary = `${canonical}.${randomUUID()}.migration`;\n await writeJsonAtomic(temporary, { version: WORKTREE_RECORD_VERSION, entries: [...entries.values()] });\n try {\n // Publish only if absent. A concurrent writer may already have added records.\n await fs.link(temporary, canonical);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;\n } finally {\n await fs.rm(temporary);\n }\n return canonical;\n}\n","import type { PoDirectEventBus } from '@agimon-ai/po-core/hubChannel';\n\nexport const GIT_WORKTREE_LIFECYCLE_EVENT = 'git_worktree_lifecycle';\nexport const GIT_WORKTREE_MESSAGE_EVENT = 'git_worktree_message';\n/**\n * A session's checkout may have changed: a tool call ended, or the agent\n * settled. Carries nothing but its version; the '# diff' channel recomputes.\n */\nexport const GIT_SESSION_CHANGED_EVENT = 'git_session_changed';\nexport const WORKTREE_MESSAGE_VERSION = 1 as const;\nexport const MAX_WORKTREE_MESSAGE_BYTES = 64 * 1024;\nexport const MAX_WORKTREE_INBOX_MESSAGES = 100;\n\nexport interface WorktreeLifecycleEvent {\n readonly version: typeof WORKTREE_MESSAGE_VERSION;\n readonly repositoryRoot: string;\n}\n\nexport type WorktreeMessageParty = 'parent' | 'child';\n\nexport interface WorktreeMessage {\n readonly version: typeof WORKTREE_MESSAGE_VERSION;\n readonly worktreeId: string;\n readonly fromSessionId: string;\n readonly from: WorktreeMessageParty;\n readonly text: string;\n readonly sentAt: string;\n}\n\nexport interface WorktreeMessageInbox {\n send(targetSessionId: string, message: WorktreeMessage): void;\n receive(worktreeId: string): WorktreeMessage[];\n close(): void;\n}\n\nfunction isMessageParty(value: unknown): value is WorktreeMessageParty {\n return value === 'parent' || value === 'child';\n}\n\nfunction parseMessage(value: unknown): WorktreeMessage | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const record = value as Partial<WorktreeMessage>;\n if (record.version !== WORKTREE_MESSAGE_VERSION) return undefined;\n if (typeof record.worktreeId !== 'string' || record.worktreeId === '') return undefined;\n if (typeof record.fromSessionId !== 'string' || record.fromSessionId === '') return undefined;\n if (!isMessageParty(record.from)) return undefined;\n if (typeof record.text !== 'string' || record.text === '') return undefined;\n if (Buffer.byteLength(record.text, 'utf8') > MAX_WORKTREE_MESSAGE_BYTES) return undefined;\n if (typeof record.sentAt !== 'string' || record.sentAt === '') return undefined;\n return record as WorktreeMessage;\n}\n\nexport function createWorktreeMessageInbox(directEvents: PoDirectEventBus, sessionId: string): WorktreeMessageInbox {\n if (sessionId === '') throw new Error('The Git message service requires a session identity.');\n const messages = new Map<string, WorktreeMessage[]>();\n const unsubscribe = directEvents.subscribe(GIT_WORKTREE_MESSAGE_EVENT, sessionId, (payload) => {\n const message = parseMessage(payload);\n if (message === undefined) return;\n const inbox = messages.get(message.worktreeId) ?? [];\n if (inbox.length >= MAX_WORKTREE_INBOX_MESSAGES) inbox.shift();\n inbox.push(message);\n messages.set(message.worktreeId, inbox);\n });\n let closed = false;\n return {\n send(targetSessionId, message) {\n if (closed) throw new Error('The Git message service is closed.');\n directEvents.publish(GIT_WORKTREE_MESSAGE_EVENT, targetSessionId, message);\n },\n receive(worktreeId) {\n if (closed) return [];\n const inbox = messages.get(worktreeId);\n if (inbox === undefined) return [];\n messages.delete(worktreeId);\n return inbox;\n },\n close() {\n if (closed) return;\n closed = true;\n unsubscribe();\n messages.clear();\n },\n };\n}\n\nexport function isWorktreeLifecycleEvent(value: unknown): value is WorktreeLifecycleEvent {\n if (typeof value !== 'object' || value === null) return false;\n const record = value as Partial<WorktreeLifecycleEvent>;\n return (\n record.version === WORKTREE_MESSAGE_VERSION &&\n typeof record.repositoryRoot === 'string' &&\n record.repositoryRoot !== ''\n );\n}\n\nexport function isSessionChangedEvent(value: unknown): boolean {\n return (\n typeof value === 'object' && value !== null && (value as { version?: unknown }).version === WORKTREE_MESSAGE_VERSION\n );\n}\n","/**\n * Naming and reconciliation rules for worktrees, as pure functions.\n *\n * Everything here is a function of its arguments so the interesting decisions,\n * which are the ones about destroying work, can be tested without a repository\n * or a filesystem.\n */\n\nimport type { WorktreeRecord } from '../../types/worktreeRegistry';\n\nconst MAX_SLUG_LENGTH = 64;\n/** Anything git forbids in a ref, plus a leading `-` that `worktree add` would read as an option. */\nconst INVALID_REF = /(^[-/.])|[\\s~^:?*[\\\\]|\\.\\.|@\\{|\\/\\/|\\/\\.|\\.lock$|\\/$|\\.$/u;\nconst MAX_REF_LENGTH = 255;\nconst FIRST_PRINTABLE = 0x20;\nconst DELETE = 0x7f;\n\n/**\n * A branch name reduced to one safe path segment.\n *\n * Slashes are the point: `wt/fix-auth` is a perfectly good branch and a\n * terrible directory name, because the nested directory it implies is not the\n * one the worktree lives in.\n */\nexport function branchSlug(branch: string): string {\n const slug = branch\n .toLowerCase()\n .replace(/[^a-z0-9]+/gu, '-')\n .replace(/^-+|-+$/gu, '')\n .slice(0, MAX_SLUG_LENGTH)\n .replace(/-+$/gu, '');\n return slug === '' ? 'worktree' : slug;\n}\n\n/**\n * The directory for one worktree.\n *\n * The short id disambiguates two branches whose slugs collide, such as\n * `feature/x` and `feature_x`, which would otherwise want the same directory.\n */\nexport function worktreeDirectory(input: {\n worktreesRoot: string;\n repositoryLabel: string;\n repositoryId: string;\n branch: string;\n shortId: string;\n}): string {\n const repository = `${input.repositoryLabel}--${input.repositoryId}`;\n return `${input.worktreesRoot}/${repository}/${branchSlug(input.branch)}--${input.shortId}`;\n}\n\n/** Why a worktree cannot be created, or undefined when it can. */\nexport function refuseSpawn(input: { branch: string; existing: readonly WorktreeRecord[] }): string | undefined {\n if (input.branch.trim() === '') return 'A branch name is required.';\n // Git refuses a second worktree on one branch, but its message names a path\n // the caller never chose, so this says it in the caller's own terms first.\n const live = input.existing.find((record) => record.branch === input.branch && record.status !== 'orphaned');\n if (live) return `Branch ${input.branch} already has a worktree (${live.id}).`;\n return undefined;\n}\n\n/** Why a worktree cannot be closed, or undefined when it can. */\nexport function refuseClose(input: {\n record: WorktreeRecord | undefined;\n dirtyFiles: readonly string[];\n force: boolean;\n}): string | undefined {\n if (!input.record) return 'No worktree with that id. Call list to see the current ids.';\n if (input.dirtyFiles.length === 0 || input.force) return undefined;\n // Naming the files is the point: \"the tree is dirty\" sends the reader to go\n // look, and the answer is usually a file they forgot rather than one they\n // meant to keep.\n const names = input.dirtyFiles.slice(0, 10).join(', ');\n const more = input.dirtyFiles.length > 10 ? `, and ${String(input.dirtyFiles.length - 10)} more` : '';\n return `${String(input.dirtyFiles.length)} uncommitted file(s): ${names}${more}. Pass force: true to discard them.`;\n}\n\nexport interface Reconciliation {\n records: WorktreeRecord[];\n /** Ids whose status changed, so a caller can report what it noticed. */\n changed: string[];\n}\n\n/**\n * Marks records whose process or directory is gone as orphaned.\n *\n * Nothing is deleted here. A po-git orphan owns a directory that may hold\n * uncommitted work, so losing the record would lose the only pointer to it.\n * Deletion is always a separate, named decision.\n */\nexport async function reconcile(\n records: readonly WorktreeRecord[],\n probe: { alive: (record: WorktreeRecord) => boolean; exists: (path: string) => boolean | Promise<boolean> },\n): Promise<Reconciliation> {\n const changed: string[] = [];\n const next: WorktreeRecord[] = [];\n for (const record of records) {\n if (record.status === 'orphaned' || ((await probe.exists(record.path)) && probe.alive(record))) {\n next.push(record);\n continue;\n }\n changed.push(record.id);\n next.push({ ...record, status: 'orphaned' });\n }\n return { records: next, changed };\n}\n\nexport interface PrunePlan {\n /** Orphans whose directory git still lists, safe to remove. */\n remove: WorktreeRecord[];\n /** Orphans whose directory is already gone; drop the record only. */\n forget: WorktreeRecord[];\n /** Paths git lists under our root that we have no record of; report, never touch. */\n untracked: string[];\n /** Orphans left alone because they still hold uncommitted work. */\n keptDirty: WorktreeRecord[];\n /**\n * Branches git refused to delete because they hold commits.\n *\n * Filled by the prune itself, not by the plan: a dry run destroys nothing, so\n * it has nothing to report here and leaves it empty.\n */\n keptBranches: string[];\n}\n\n/**\n * What a prune would do, decided before anything is destroyed.\n *\n * Separating the plan from the execution is what makes dryRun honest and lets\n * the destructive half be reviewed on its own.\n */\nexport function planPrune(input: {\n records: readonly WorktreeRecord[];\n gitPaths: readonly string[];\n worktreesRoot: string;\n dirtyByPath: ReadonlyMap<string, readonly string[]>;\n}): PrunePlan {\n const plan: PrunePlan = { remove: [], forget: [], untracked: [], keptDirty: [], keptBranches: [] };\n const known = new Set(input.records.map((record) => record.path));\n const listed = new Set(input.gitPaths);\n for (const record of input.records) {\n if (record.status !== 'orphaned') continue;\n if (!listed.has(record.path)) {\n plan.forget.push(record);\n continue;\n }\n if ((input.dirtyByPath.get(record.path) ?? []).length > 0) {\n plan.keptDirty.push(record);\n continue;\n }\n plan.remove.push(record);\n }\n for (const path of input.gitPaths) {\n // Only ever inside our own root: a worktree the user made by hand is none\n // of this package's business, even when it looks abandoned.\n if (path.startsWith(`${input.worktreesRoot}/`) && !known.has(path)) plan.untracked.push(path);\n }\n return plan;\n}\n\n/** Whether a user-supplied branch or base ref is safe to hand to git as a positional argument. */\nexport function validRefName(name: string): boolean {\n if (name === '' || name === '@' || name.length > MAX_REF_LENGTH || INVALID_REF.test(name)) return false;\n for (const character of name) {\n const code = character.charCodeAt(0);\n if (code < FIRST_PRINTABLE || code === DELETE) return false;\n }\n return true;\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { setTimeout } from 'node:timers/promises';\n\nimport {\n WORKTREE_RECORD_VERSION,\n type WorktreeRecord,\n type WorktreeRegistryFile,\n type WorktreeRegistryStore,\n} from '../../types/worktreeRegistry';\nimport { readJson, writeJsonAtomic } from '../atomicJson';\nimport { PoGitExpectedError } from '../errors';\n\nconst LOCK_WAIT_MS = 5000;\nconst LOCK_RETRY_MS = 25;\n\nfunction isRecord(value: unknown): value is WorktreeRecord {\n if (typeof value !== 'object' || value === null) return false;\n const record = value as Partial<WorktreeRecord>;\n return (\n record.version === WORKTREE_RECORD_VERSION &&\n typeof record.id === 'string' &&\n record.id !== '' &&\n typeof record.path === 'string' &&\n typeof record.branch === 'string' &&\n typeof record.sessionId === 'string'\n );\n}\n\n/**\n * Repository mutations hold an exclusive directory lock from the read through\n * the final commit. This works across independently loaded packages and hosts.\n * A crashed owner leaves a visible lock, never a lease another writer may steal.\n */\nexport function createWorktreeRegistry(file: string): WorktreeRegistryStore {\n return {\n async list() {\n const parsed = await readJson<WorktreeRegistryFile>(file);\n if (!parsed || parsed.version !== WORKTREE_RECORD_VERSION || !Array.isArray(parsed.entries)) return [];\n return parsed.entries.filter(isRecord);\n },\n async replace(entries) {\n await writeJsonAtomic(file, { version: WORKTREE_RECORD_VERSION, entries } satisfies WorktreeRegistryFile);\n },\n async transaction(operation, signal) {\n const lock = `${file}.lock`;\n await fs.mkdir(path.dirname(file), { recursive: true });\n const deadline = Date.now() + LOCK_WAIT_MS;\n for (;;) {\n signal?.throwIfAborted();\n try {\n await fs.mkdir(lock, { mode: 0o700 });\n break;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;\n if (Date.now() >= deadline)\n throw new PoGitExpectedError(\n 'registry_busy',\n 'Another worktree operation holds the repository registry.',\n true,\n 'Retry after it finishes. After a host crash, inspect and remove the abandoned worktrees.json.lock directory.',\n );\n await setTimeout(LOCK_RETRY_MS, undefined, { signal });\n }\n }\n try {\n await fs.writeFile(\n path.join(lock, 'owner.json'),\n JSON.stringify({ pid: process.pid, createdAt: new Date().toISOString() }),\n { mode: 0o600 },\n );\n signal?.throwIfAborted();\n return await operation();\n } finally {\n await fs.rm(lock, { recursive: true });\n }\n },\n };\n}\n","import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport type { PoHubSessionService } from '@agimon-ai/po-core/hubChannel';\nimport type { PoSessionDeliveryService } from '@agimon-ai/po-session';\nimport { load } from 'js-yaml';\n\nimport { WORKTREE_CONFIG_FILE, WORKTREE_SETUP_LAUNCH } from '../../constants/git';\nimport { WORKTREE_RECORD_VERSION } from '../../types/worktreeRegistry';\nimport type { WorktreeGit, WorktreeRecord } from '../../types/worktreeRegistry';\nimport { PoGitExpectedError, HubUnavailableError } from '../errors';\nimport { registryFile, worktreesRoot } from '../paths';\nimport { repositoryId, repositoryLabel, shortId } from '../repositoryIdentity';\nimport { MAX_WORKTREE_MESSAGE_BYTES, type WorktreeMessageInbox, type WorktreeMessageParty } from '../worktreeEvents';\nimport { planPrune, reconcile, refuseClose, refuseSpawn, validRefName, worktreeDirectory } from '../worktreeNaming';\nimport { createWorktreeRegistry } from '../worktreeRegistry';\n\nconst GIT_WORKTREE_DELEGATION_KIND = 'git.worktree.delegation';\nconst GIT_WORKTREE_MESSAGE_KIND = 'git.worktree.message';\nconst GIT_WORKTREE_REPORT_KIND = 'git.worktree.report';\n\n/**\n * The repository's worktree setup as one shell command, or undefined when it asks for none.\n * Read from the checkout the spawn starts in, so an uncommitted edit applies at once.\n */\nasync function readWorktreeSetup(root: string): Promise<string | undefined> {\n const file = path.join(root, WORKTREE_CONFIG_FILE);\n let setup: unknown;\n try {\n setup = (load(await fs.readFile(file, 'utf8')) as { setup?: unknown } | null | undefined)?.setup;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined;\n throw new PoGitExpectedError(\n 'invalid_request',\n `${WORKTREE_CONFIG_FILE} is not valid YAML (${(error as Error).message}).`,\n false,\n 'Fix the file and try again.',\n );\n }\n const commands: unknown[] = [setup ?? []].flat();\n if (!commands.every((command): command is string => typeof command === 'string'))\n throw new PoGitExpectedError(\n 'invalid_request',\n `${WORKTREE_CONFIG_FILE} setup must be a command or a list of commands.`,\n false,\n 'Fix the file and try again.',\n );\n // Each step runs only when the one before it succeeded, so a failed install never builds.\n return commands.filter((command) => command.trim() !== '').join(' && ') || undefined;\n}\nexport interface WorktreeContext {\n /** Where the calling session is working, used to find the repository. */\n cwd: string;\n /**\n * The calling session, recorded as the new session's parent. Absent when the\n * new-session dialog opens a top-level worktree session for the workspace.\n */\n sessionId?: string;\n}\n\nexport interface SpawnWorktreeRequest {\n branch: string;\n baseRef?: string;\n name?: string;\n task?: string;\n /** Host-owned execution setup, exposed by the UI rather than the agent tool. */\n reservationId?: string;\n /** `existing` checks out a branch that already exists instead of creating one from `baseRef`. */\n checkout?: 'new' | 'existing';\n /** With `existing`: the branch exists only on this remote; a local tracking branch is created. */\n remote?: string;\n}\n\nexport interface SpawnOptions {\n /** Aborted when the caller gives up, so a spawn nobody is waiting for stops. */\n signal?: AbortSignal;\n /** Phase labels, for a caller that can show them while the work runs. */\n onProgress?: (label: string) => void;\n}\n\nexport interface WorktreeOperations {\n spawn(context: WorktreeContext, request: SpawnWorktreeRequest, options?: SpawnOptions): Promise<WorktreeRecord>;\n close(context: WorktreeContext, id: string, force: boolean): Promise<WorktreeRecord>;\n list(context: WorktreeContext): Promise<WorktreeRecord[]>;\n status(context: WorktreeContext, id: string): Promise<{ record: WorktreeRecord; dirtyFiles: string[] }>;\n merge(context: WorktreeContext, id: string, message?: string): Promise<WorktreeRecord>;\n prune(context: WorktreeContext, dryRun: boolean): Promise<ReturnType<typeof planPrune>>;\n send(context: WorktreeContext, id: string, message: string): Promise<void>;\n messages(context: WorktreeContext, id: string): Promise<import('../worktreeEvents').WorktreeMessage[]>;\n}\n\nexport interface WorktreeOperationsDeps {\n git: WorktreeGit;\n /** The canonical hub-owned session lifecycle. */\n sessionService?: PoHubSessionService;\n /** Legacy in-memory fallback used outside the fixed Session composition. */\n messageInbox?: WorktreeMessageInbox;\n /** Reads the active Session provider when an operation executes. */\n sessionDelivery?: () => PoSessionDeliveryService | undefined;\n homeDir?: string;\n /** Injected so a record's createdAt is reproducible in a test. */\n now?: () => Date;\n}\n\nexport function createWorktreeOperations(deps: WorktreeOperationsDeps): WorktreeOperations {\n const { git } = deps;\n const sessionService = deps.sessionService;\n const now = deps.now ?? (() => new Date());\n const requireSessionService = (): PoHubSessionService => {\n if (sessionService === undefined)\n throw new HubUnavailableError('The cockpit session service is unavailable. Start the cockpit and try again.');\n return sessionService;\n };\n const requireMessageInbox = (): WorktreeMessageInbox => {\n if (deps.messageInbox === undefined)\n throw new HubUnavailableError('The Git message service is unavailable. Start the cockpit and try again.');\n return deps.messageInbox;\n };\n const readSessionDelivery = (): PoSessionDeliveryService | undefined => deps.sessionDelivery?.();\n const requireSessionDelivery = (): PoSessionDeliveryService => {\n const delivery = readSessionDelivery();\n if (delivery === undefined)\n throw new HubUnavailableError('The Session delivery service is unavailable. Start the cockpit and try again.');\n return delivery;\n };\n const probe = {\n alive: (record: WorktreeRecord) => requireSessionService().isLive(record.sessionId),\n exists: (path: string) =>\n fs.access(path).then(\n () => true,\n () => false,\n ),\n };\n\n /**\n * Everything an action needs about the repository it is acting on.\n *\n * Resolved per call rather than cached: a session's cwd is stable, but the\n * worktree registry is shared and another process may have written it since\n * the last call.\n */\n const resolve = async (context: WorktreeContext) => {\n const root = await git.repositoryRoot(context.cwd);\n if (root === undefined) {\n throw new PoGitExpectedError(\n 'not_a_repository',\n `${context.cwd} is not inside a git repository.`,\n false,\n 'Run this from a repository checkout.',\n );\n }\n const store = createWorktreeRegistry(await registryFile(root, deps.homeDir));\n return { root, store, records: await store.list() };\n };\n\n const require = (records: readonly WorktreeRecord[], id: string): WorktreeRecord => {\n const record = records.find((entry) => entry.id === id);\n if (record === undefined) {\n throw new PoGitExpectedError(\n 'worktree_not_found',\n `No worktree with id ${id}.`,\n false,\n 'Call list to see the current ids.',\n );\n }\n return record;\n };\n\n /**\n * Refuses to destroy or merge a worktree another live session is using.\n *\n * `parentSessionId` records who asked for the worktree. Two sessions in one\n * checkout share this registry, so without the check either could close the\n * other's work in progress by id.\n *\n * Once that session is gone there is no owner left to protect, and refusing\n * would strand the worktree: nothing else could ever close it.\n */\n const requireOwner = (context: WorktreeContext, record: WorktreeRecord, action: string): void => {\n if (record.parentSessionId === context.sessionId) return;\n if (record.parentSessionId === undefined || !requireSessionService().isLive(record.parentSessionId)) return;\n throw new PoGitExpectedError(\n 'worktree_not_owned',\n `Worktree ${record.id} belongs to another session.`,\n false,\n `Ask the session that created it to ${action} it, or close that session first.`,\n );\n };\n\n const peerFor = (\n context: WorktreeContext,\n record: WorktreeRecord,\n ): { sessionId: string; party: WorktreeMessageParty } => {\n if (record.parentSessionId === undefined)\n throw new PoGitExpectedError(\n 'worktree_peer_unavailable',\n `Worktree ${record.id} was opened on its own and has no parent session to message.`,\n false,\n 'Message a worktree this session created.',\n );\n if (context.sessionId === record.parentSessionId) return { sessionId: record.sessionId, party: 'parent' };\n if (context.sessionId === record.sessionId) return { sessionId: record.parentSessionId, party: 'child' };\n throw new PoGitExpectedError(\n 'worktree_not_owned',\n `Worktree ${record.id} belongs to another session.`,\n false,\n 'Use a worktree owned by this session.',\n );\n };\n\n const requirePeerLive = (peerSessionId: string): void => {\n if (!requireSessionService().isLive(peerSessionId)) {\n throw new PoGitExpectedError(\n 'worktree_peer_unavailable',\n 'The other worktree session is no longer live.',\n false,\n 'Start a new worktree session before sending a message.',\n );\n }\n };\n\n const operations: WorktreeOperations = {\n async spawn(context, request, options) {\n const parentSessionId = context.sessionId;\n const parented = parentSessionId === undefined ? {} : { parentSessionId };\n const { root, store, records } = await resolve(context);\n const reservations = request.reservationId === undefined ? undefined : requireSessionService().reservations;\n if (request.reservationId !== undefined && (!reservations || request.task !== undefined))\n throw new PoGitExpectedError(\n 'invalid_request',\n 'Reserved worktree sessions require host setup and cannot start a task.',\n false,\n 'Create the session from its pending setup card.',\n );\n const reserved =\n request.reservationId === undefined ? undefined : reservations!.read(request.reservationId, parentSessionId!);\n const existing =\n reserved === undefined ? undefined : records.find((record) => record.sessionId === reserved.sessionId);\n if (existing) {\n const expectedPath = worktreeDirectory({\n worktreesRoot: worktreesRoot(deps.homeDir),\n repositoryLabel: repositoryLabel(root),\n repositoryId: await repositoryId(root),\n branch: request.branch,\n shortId: shortId(reserved!.sessionId),\n });\n if (\n existing.parentSessionId !== parentSessionId ||\n existing.repositoryRoot !== root ||\n existing.branch !== request.branch ||\n existing.path !== expectedPath ||\n existing.path !== reserved?.cwd ||\n (request.baseRef !== undefined && existing.baseRef !== request.baseRef) ||\n !(await probe.exists(existing.path)) ||\n !(await git.listWorktreePaths(root)).includes(existing.path) ||\n (await git.repositoryRoot(existing.path)) !== existing.path ||\n (await git.currentBranch(existing.path)) !== request.branch\n )\n throw new PoGitExpectedError(\n 'invalid_request',\n 'The reserved checkout no longer matches this setup.',\n false,\n 'Inspect the existing branch and checkout; they will not be replaced.',\n );\n if (!requireSessionService().isLive(existing.sessionId)) {\n const session = await requireSessionService().create({\n cwd: existing.path,\n name: request.name ?? request.branch,\n parentSessionId,\n sessionProvenance: 'worktree',\n reservationId: request.reservationId,\n ...(options?.signal === undefined ? {} : { signal: options.signal }),\n });\n if (session.sessionId !== existing.sessionId)\n throw new Error('The host did not use the reserved session identity.');\n }\n await reservations!.complete(request.reservationId!, parentSessionId!);\n return existing;\n }\n const refusal = refuseSpawn({ branch: request.branch, existing: records });\n if (refusal !== undefined) {\n throw new PoGitExpectedError('worktree_exists', refusal, false, 'Pick another branch name, or close it.');\n }\n const taskDelivery = request.task === undefined ? undefined : requireSessionDelivery();\n // Read before any Git state exists, so a broken file refuses the spawn instead of half-running it.\n const setup = await readWorktreeSetup(root);\n const existingBranch = request.checkout === 'existing';\n const id = shortId(reserved?.sessionId ?? randomUUID());\n let path = worktreeDirectory({\n worktreesRoot: worktreesRoot(deps.homeDir),\n repositoryLabel: repositoryLabel(root),\n repositoryId: await repositoryId(root),\n branch: request.branch,\n shortId: id,\n });\n if (request.reservationId !== undefined) {\n path = (await reservations!.prepare(request.reservationId, parentSessionId!, path)).cwd;\n }\n const recovering = reserved?.cwd !== undefined && (await probe.exists(path));\n if (\n recovering &&\n (!(await git.listWorktreePaths(root)).includes(path) || (await git.currentBranch(path)) !== request.branch)\n )\n throw new PoGitExpectedError(\n 'invalid_request',\n 'The reserved checkout no longer matches this setup.',\n false,\n 'Inspect the existing directory; it will not be replaced.',\n );\n if (!recovering) {\n if (existingBranch) {\n const branches = await git.listBranches(root);\n const local = branches.local.find((branch) => branch.name === request.branch);\n const available =\n request.remote === undefined\n ? local !== undefined && local.checkedOutAt === undefined\n : local === undefined &&\n branches.remote.some((branch) => branch.remote === request.remote && branch.name === request.branch);\n if (!available)\n throw new PoGitExpectedError(\n 'invalid_request',\n local?.checkedOutAt === undefined\n ? `The branch ${request.branch} is not available to check out.`\n : `The branch ${request.branch} is already checked out at ${local.checkedOutAt}.`,\n false,\n 'Pick another branch, or create a new one.',\n );\n } else {\n // ponytail: the branch list caps at 2,000 refs; use show-ref --verify if older duplicates need covering.\n if ((await git.listBranches(root)).local.some((branch) => branch.name === request.branch))\n throw new PoGitExpectedError(\n 'invalid_request',\n `The branch ${request.branch} already exists.`,\n false,\n 'Pick another name, or open it as an existing branch.',\n );\n }\n }\n const baseRef = existingBranch\n ? request.remote === undefined\n ? request.branch\n : `${request.remote}/${request.branch}`\n : (request.baseRef ?? (await git.remoteBaseRef(root)));\n if (baseRef === undefined) {\n throw new PoGitExpectedError(\n 'git_failed',\n 'No remote base branch is available for this repository.',\n false,\n 'Fetch a remote branch or pass an explicit baseRef.',\n );\n }\n // The worktree and the branch are made by one command, so they are undone\n // by one too. `worktree remove` leaves the branch behind, and a branch\n // nobody asked for is what a failed spawn used to leave on the floor.\n const cancelled = (): boolean => options?.signal?.aborted === true;\n const rollback = async (): Promise<string> => {\n if (reserved) return ` The reserved checkout at ${path} was retained for recovery.`;\n await git.removeWorktree({ repositoryRoot: root, path, force: true }).catch(() => undefined);\n // A branch that existed before this spawn is never deleted; only one it created is.\n if (existingBranch && request.remote === undefined) return '';\n const deleted = await git.deleteBranch({ repositoryRoot: root, branch: request.branch }).catch(() => false);\n return deleted ? '' : ` The branch ${request.branch} has work on it and was kept.`;\n };\n\n options?.onProgress?.(`creating branch ${request.branch}\\u2026`);\n if (!recovering) {\n if (existingBranch)\n await git.addExistingWorktree({\n repositoryRoot: root,\n path,\n branch: request.branch,\n ...(request.remote === undefined ? {} : { remote: request.remote }),\n });\n else await git.addWorktree({ repositoryRoot: root, path, branch: request.branch, baseRef });\n }\n\n // Checked here rather than only inside the session call: this is the\n // point where a checkout exists that nothing has recorded yet, which is\n // exactly the state an interrupted spawn used to leave behind.\n if (cancelled()) {\n const kept = await rollback();\n throw new PoGitExpectedError(\n 'spawn_cancelled',\n `Cancelled before the session started.${kept}`,\n false,\n reserved\n ? 'Retry setup with the same branch to recover the reserved checkout.'\n : 'The worktree was removed; run it again when you are ready.',\n );\n }\n\n // The worktree exists from here on, so every later failure has to leave\n // it removed or recorded. An unrecorded directory on disk is the one\n // outcome with no way back: nothing would ever list it again.\n options?.onProgress?.('starting session\\u2026');\n let sessionId: string;\n try {\n const session = await requireSessionService().create({\n cwd: path,\n name: request.name ?? request.branch,\n ...parented,\n sessionProvenance: 'worktree',\n ...(options?.signal === undefined ? {} : { signal: options.signal }),\n ...(request.reservationId === undefined ? {} : { reservationId: request.reservationId }),\n });\n sessionId = session.sessionId;\n if (reserved && sessionId !== reserved.sessionId)\n throw new Error('The host did not use the reserved session identity.');\n } catch (error) {\n const kept = await rollback();\n if (cancelled()) {\n throw new PoGitExpectedError(\n 'spawn_cancelled',\n `Cancelled while the session was starting.${kept}`,\n false,\n reserved\n ? 'Retry setup with the same branch to recover the reserved checkout.'\n : 'The worktree was removed; run it again when you are ready.',\n );\n }\n if (error instanceof HubUnavailableError) {\n throw new PoGitExpectedError(\n 'hub_unavailable',\n `${error.message}${kept}`,\n true,\n 'Start the cockpit and try again.',\n );\n }\n throw error;\n }\n\n const record: WorktreeRecord = {\n version: WORKTREE_RECORD_VERSION,\n id,\n branch: request.branch,\n baseRef,\n path,\n repositoryRoot: root,\n sessionId,\n ...parented,\n status: 'running',\n createdAt: now().toISOString(),\n };\n try {\n await store.replace([...records, record]);\n } catch (error) {\n // A live session with no record is the worst outcome available here:\n // it runs, and no id anything can name points at it. The session goes\n // back too, rather than being left for someone to find by hand.\n await requireSessionService()\n .close(sessionId)\n .catch(() => undefined);\n const kept = await rollback();\n throw new PoGitExpectedError(\n 'registry_write_failed',\n `The worktree was created but the registry could not be written (${(error as Error).message}).${kept}`,\n true,\n 'Check the registry file for permissions or free space, then try again.',\n );\n }\n // Started through the session's own po-runner command, so it runs in the checkout, belongs\n // to that session, and its log stays readable there. A failed start keeps the worktree.\n let setupStarted = false;\n if (setup !== undefined) {\n try {\n const service = requireSessionService();\n if (service.prompt === undefined) throw new Error('this host cannot run session commands');\n await service.prompt(sessionId, `${WORKTREE_SETUP_LAUNCH} ${setup}`);\n setupStarted = true;\n } catch (error) {\n options?.onProgress?.(`worktree setup did not start (${String(error)})`);\n }\n }\n if (request.task !== undefined && taskDelivery !== undefined) {\n try {\n const receipt = await taskDelivery.deliver({\n recipientKey: sessionId,\n kind: GIT_WORKTREE_DELEGATION_KIND,\n prompt: setupStarted\n ? `${request.task}\\n\\nThe worktree setup (${setup}) is running as the runner \"worktree-setup\". Check it with po-runner before relying on installed dependencies or builds.`\n : request.task,\n metadata: {\n worktreeId: record.id,\n fromRole: 'parent',\n text: request.task,\n sentAt: record.createdAt,\n },\n });\n const admission = await taskDelivery.waitForAdmission(receipt.deliveryId);\n if (admission !== 'admitted') {\n throw new PoGitExpectedError(\n 'task_delivery_failed',\n `Worktree ${record.id} was created and task delivery ${receipt.deliveryId} was persisted, but admission ${admission === 'recovery_required' ? 'requires recovery' : 'was not confirmed before the timeout'}.`,\n true,\n admission === 'recovery_required'\n ? `Call messages from worktree ${record.id} to recover the task in the recipient session. Do not resend it automatically.`\n : `Check delivery ${receipt.deliveryId} in the sender outbox or call messages from worktree ${record.id} in the recipient session before deciding whether to resend.`,\n );\n }\n } catch (error) {\n if (error instanceof PoGitExpectedError) throw error;\n throw new PoGitExpectedError(\n 'task_delivery_failed',\n `Worktree ${record.id} was created, but task delivery failed (${String(error)}).`,\n true,\n `Inspect worktree ${record.id} and the sender outbox before using send to deliver the task. Do not recreate the worktree.`,\n );\n }\n }\n if (request.reservationId !== undefined) await reservations!.complete(request.reservationId, parentSessionId!);\n return record;\n },\n\n async close(context, id, force) {\n const { root, store, records } = await resolve(context);\n const record = require(records, id);\n requireOwner(context, record, 'close');\n const dirtyFiles = (await probe.exists(record.path)) ? await git.dirtyFiles(record.path) : [];\n const refusal = refuseClose({ record, dirtyFiles, force });\n if (refusal !== undefined) {\n throw new PoGitExpectedError('worktree_dirty', refusal, false, 'Commit the work, or pass force: true.');\n }\n // The session is stopped before the directory goes. Removing a checkout\n // while a process still holds files open in it is how a half-removed\n // worktree and a stale git administrative entry are made.\n await requireSessionService().close(record.sessionId);\n await git.removeWorktree({ repositoryRoot: root, path: record.path, force });\n await store.replace(records.filter((entry) => entry.id !== id));\n return record;\n },\n\n async list(context) {\n const { store, records } = await resolve(context);\n const outcome = await reconcile(records, probe);\n if (outcome.changed.length > 0) await store.replace(outcome.records);\n return outcome.records;\n },\n\n async status(context, id) {\n const { records } = await resolve(context);\n const record = require(records, id);\n const dirtyFiles = (await probe.exists(record.path)) ? await git.dirtyFiles(record.path) : [];\n return { record, dirtyFiles };\n },\n\n async merge(context, id, message) {\n const { root, records } = await resolve(context);\n const record = require(records, id);\n requireOwner(context, record, 'merge');\n // The merge lands in the parent, so the parent is what must be clean. A\n // dirty parent would mix the person's in-flight edits into a merge commit\n // they did not intend to make.\n const parentDirty = await git.dirtyFiles(root);\n if (parentDirty.length > 0) {\n throw new PoGitExpectedError(\n 'worktree_dirty',\n `The parent checkout has ${String(parentDirty.length)} uncommitted file(s): ${parentDirty.slice(0, 10).join(', ')}.`,\n false,\n 'Commit or stash the parent checkout first.',\n );\n }\n await git.mergeBranch({\n repositoryRoot: root,\n branch: record.branch,\n ...(message === undefined ? {} : { message }),\n });\n return record;\n },\n\n /** Sends only between the parent session and its own worktree session. */\n async send(context, id, message) {\n if (Buffer.byteLength(message, 'utf8') > MAX_WORKTREE_MESSAGE_BYTES) {\n throw new PoGitExpectedError(\n 'message_too_large',\n `A message may not exceed ${String(MAX_WORKTREE_MESSAGE_BYTES)} bytes.`,\n false,\n 'Send a shorter message.',\n );\n }\n const { records } = await resolve(context);\n const record = require(records, id);\n const peer = peerFor(context, record);\n requirePeerLive(peer.sessionId);\n const sentAt = new Date().toISOString();\n const delivery = readSessionDelivery();\n if (delivery !== undefined) {\n const kind = peer.party === 'parent' ? GIT_WORKTREE_MESSAGE_KIND : GIT_WORKTREE_REPORT_KIND;\n const receipt = await delivery.deliver({\n recipientKey: peer.sessionId,\n kind,\n prompt:\n peer.party === 'parent'\n ? `Parent message for worktree ${record.id}:\\n\\n${message}`\n : `Report from worktree ${record.id}:\\n\\n${message}`,\n metadata: { worktreeId: record.id, fromRole: peer.party, text: message, sentAt },\n });\n const admission = await delivery.waitForAdmission(receipt.deliveryId);\n if (admission !== 'admitted') {\n throw new PoGitExpectedError(\n 'message_delivery_failed',\n `Worktree ${record.id} persisted message delivery ${receipt.deliveryId}, but admission ${admission === 'recovery_required' ? 'requires recovery' : 'was not confirmed before the timeout'}.`,\n true,\n admission === 'recovery_required'\n ? `Call messages from the recipient session to recover delivery ${receipt.deliveryId}. Do not resend it automatically.`\n : `Check delivery ${receipt.deliveryId} in the sender outbox or call messages from the recipient session before deciding whether to resend.`,\n );\n }\n return;\n }\n requireMessageInbox().send(peer.sessionId, {\n version: 1,\n worktreeId: record.id,\n // peerFor only answers for the worktree's parent or child session, so the caller has one.\n fromSessionId: context.sessionId!,\n from: peer.party,\n text: message,\n sentAt,\n });\n },\n\n async messages(context, id) {\n const { records } = await resolve(context);\n const record = require(records, id);\n const peer = peerFor(context, record);\n const delivery = readSessionDelivery();\n if (delivery === undefined) return requireMessageInbox().receive(record.id);\n const entries = (await delivery.inbox({ consumed: false, metadata: { worktreeId: record.id } })).filter(\n (entry) =>\n entry.senderKey === peer.sessionId &&\n (entry.state === 'admitted' || entry.state === 'recovery_required') &&\n (peer.party === 'parent'\n ? entry.kind === GIT_WORKTREE_REPORT_KIND\n : entry.kind === GIT_WORKTREE_MESSAGE_KIND || entry.kind === GIT_WORKTREE_DELEGATION_KIND),\n );\n for (const entry of entries) await delivery.consume(entry.deliveryId);\n return entries.map((entry) => ({\n version: 1,\n worktreeId: record.id,\n fromSessionId: entry.senderKey,\n from: peer.party === 'parent' ? ('child' as const) : ('parent' as const),\n text:\n entry.state === 'recovery_required'\n ? `[Recovery required: prompt admission was not confirmed] ${entry.metadata.text ?? entry.prompt}`\n : (entry.metadata.text ?? entry.prompt),\n sentAt: entry.metadata.sentAt ?? '',\n }));\n },\n\n async prune(context, dryRun) {\n const { root, store, records } = await resolve(context);\n const reconciled = await reconcile(records, probe);\n const gitPaths = await git.listWorktreePaths(root);\n const dirtyByPath = new Map<string, readonly string[]>();\n for (const record of reconciled.records) {\n if (record.status === 'orphaned' && (await probe.exists(record.path))) {\n dirtyByPath.set(record.path, await git.dirtyFiles(record.path));\n }\n }\n const plan = planPrune({\n records: reconciled.records,\n gitPaths,\n worktreesRoot: worktreesRoot(deps.homeDir),\n dirtyByPath,\n });\n if (dryRun) {\n await store.replace(reconciled.records);\n return plan;\n }\n for (const record of plan.remove) {\n await git.removeWorktree({ repositoryRoot: root, path: record.path, force: false });\n }\n // The checkout goes, so the branch it was made for goes with it. Safe\n // delete only: git keeps anything holding commits, and the plan says\n // which ones it kept rather than leaving the reader to notice later.\n for (const record of [...plan.remove, ...plan.forget]) {\n const deleted = await git.deleteBranch({ repositoryRoot: root, branch: record.branch }).catch(() => false);\n if (!deleted) plan.keptBranches.push(record.branch);\n }\n const dropped = new Set([...plan.remove, ...plan.forget].map((record) => record.id));\n await store.replace(reconciled.records.filter((record) => !dropped.has(record.id)));\n return plan;\n },\n };\n const locked = async <T>(context: WorktreeContext, operation: () => Promise<T>, signal?: AbortSignal): Promise<T> => {\n try {\n const { store } = await resolve(context);\n return await store.transaction(operation, signal);\n } catch (error) {\n if (signal?.aborted && !(error instanceof PoGitExpectedError))\n throw new PoGitExpectedError(\n 'spawn_cancelled',\n 'The worktree operation was cancelled.',\n false,\n 'Inspect its recorded state before retrying.',\n );\n if (['ENOTDIR', 'EACCES', 'EROFS', 'ENOSPC'].includes(String((error as NodeJS.ErrnoException).code)))\n throw new PoGitExpectedError(\n 'registry_write_failed',\n 'The worktree registry is not writable.',\n true,\n 'Check permissions and free space before retrying.',\n );\n throw error;\n }\n };\n // ponytail: serialize Git lifecycle mutations, not session execution. Keeping\n // the lock across startup avoids a second lease system for partially created trees.\n return {\n ...operations,\n spawn: (context, request, options) => {\n if (sessionService === undefined)\n return Promise.reject(\n new PoGitExpectedError(\n 'hub_unavailable',\n 'The cockpit session service is unavailable.',\n true,\n 'Use the cockpit worktree tool after its Git server plugin is available.',\n ),\n );\n // Checked before the repository lock, so unsafe input never reaches git at all.\n if (!validRefName(request.branch) || (request.baseRef !== undefined && !validRefName(request.baseRef)))\n return Promise.reject(\n new PoGitExpectedError('invalid_request', 'That is not a valid branch name.', false, 'Pick another name.'),\n );\n if (request.reservationId !== undefined && context.sessionId === undefined)\n return Promise.reject(\n new PoGitExpectedError(\n 'invalid_request',\n 'A reserved worktree session requires its owning parent.',\n false,\n 'Create the session from its pending setup card.',\n ),\n );\n return locked(context, () => operations.spawn(context, request, options), options?.signal);\n },\n close: (context, id, force) => locked(context, () => operations.close(context, id, force)),\n list: (context) => locked(context, () => operations.list(context)),\n merge: (context, id, message) => locked(context, () => operations.merge(context, id, message)),\n prune: (context, dryRun) => locked(context, () => operations.prune(context, dryRun)),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgBA,MAAa,kBAAkB;AAC/B,MAAM,iBAAiB;AACvB,MAAM,oBAAoB;AAC1B,MAAM,mBAAmB;;AAEzB,MAAa,qBAAqB;;AAElC,MAAa,oBAAoB;AACjC,MAAM,mBAAmB;;AAEzB,MAAM,kBAAkB;AACxB,MAAM,eAAe;AACrB,MAAM,gBAAgB;AACtB,MAAM,cAAc;;;;;;;;;;;;AA8BpB,SAAgB,OAAO,KAAa,MAAyB,SAA4C;CACvG,OAAO,IAAI,SAAS,YAAY;EAC9B,CAAA,GAAA,mBAAA,SAAA,CACE,OACA,CAAC,GAAG,IAAI,GACR;GACE;GACA,SAAS,QAAQ;GACjB,WAAW,QAAQ,aAAa;GAChC,KAAK;IAAE,GAAI,QAAQ,OAAO,QAAQ;IAAM,QAAQ;GAAI;EACtD,IACC,OAAO,QAAQ,WAAW;GACzB,MAAM,UAAU;GAEhB,QAAQ;IACN,MAFW,WAAW,OAAO,QAAQ,SAAS,WAAW,QAAQ,OAAO,UAAU,IAAI;IAGtF,QAAQ,OAAO,MAAM;IACrB,QAAQ,OAAO,MAAM;IACrB,UAAU,SAAS,WAAW,QAAQ,QAAQ,SAAS;IACvD,UAAU,SAAS,SAAS;GAC9B,CAAC;EACH,CACF;CACF,CAAC;AACH;AAEA,SAAS,IAAI,KAAa,MAAyB,SAAqC;CACtF,OAAO,OAAO,KAAK,MAAM,EAAE,QAAQ,CAAC;AACtC;;;;;;;AAQA,SAAS,QAAQ,WAAmB,QAA0B;CAC5D,uBAAO,IAAI,MACT,OAAO,UAAU,gBAAgB,OAAO,OAAO,IAAI,EAAE,IAAI,OAAO,OAAO,OAAO,MAAM,EAAE,kBACxF;AACF;;AAGA,SAAS,gBAAgB,QAAyB;CAChD,MAAM,aAAa,OAAO,YAAY;CACtC,OAAO,WAAW,SAAS,uBAAuB,KAAK,WAAW,SAAS,4BAA4B;AACzG;AAEA,SAAgB,oBAAiC;CAC/C,MAAM,QAAQ,OAAO,mBAA0C;EAC7D,MAAM,IAAI,gBAAgB,CAAC,YAAY,OAAO,GAAG,gBAAgB;CACnE;CAEA,OAAO;EACL,MAAM,YAAY,EAAE,gBAAgB,MAAM,QAAQ,WAAW;GAC3D,MAAM,SAAS,MAAM,IAAI,gBAAgB;IAAC;IAAY;IAAO;IAAM;IAAQ;IAAM;GAAO,GAAG,cAAc;GACzG,IAAI,OAAO,SAAS,GAAG,MAAM,QAAQ,gBAAgB,MAAM;EAC7D;EAEA,MAAM,oBAAoB,EAAE,gBAAgB,MAAM,QAAQ,UAAU;GAKlE,MAAM,SAAS,MAAM,IAAI,gBAHvB,WAAW,KAAA,IACP;IAAC;IAAY;IAAO;IAAM;GAAM,IAChC;IAAC;IAAY;IAAO;IAAW;IAAM;IAAQ;IAAM,GAAG,OAAO,GAAG;GAAQ,GAC/B,cAAc;GAC7D,IAAI,OAAO,SAAS,GAAG,MAAM,QAAQ,gBAAgB,MAAM;EAC7D;EAEA,MAAM,aAAa,gBAAsC;GACvD,MAAM,OAAO,MAAM,IACjB,gBACA;IACE;IACA;IACA,WAAW,OAAO,eAAe;IACjC;IACA;IACA;GACF,GACA,eACF;GACA,IAAI,KAAK,SAAS,GAAG,MAAM,QAAQ,gBAAgB,IAAI;GACvD,MAAM,QAA0B,CAAC;GACjC,MAAM,UAA6B,CAAC;GACpC,KAAK,MAAM,QAAQ,KAAK,OAAO,MAAM,IAAI,GAAG;IAC1C,MAAM,CAAC,MAAM,IAAI,eAAe,IAAI,SAAS,MAAM,KAAK,MAAM,GAAI;IAClE,IAAI,QAAQ,MAAM,WAAW,IAAI;IACjC,IAAI,IAAI,WAAW,YAAY,GAAG;KAChC,MAAM,OAAO,IAAI,MAAM,EAAmB;KAC1C,MAAM,KAAK,iBAAiB,KAAK,EAAE,KAAK,IAAI;MAAE;MAAM,cAAc;KAAa,CAAC;IAClF,OAAO,IAAI,IAAI,WAAW,aAAa,KAAK,CAAC,IAAI,SAAS,WAAW,GAAG;KACtE,MAAM,OAAO,IAAI,MAAM,EAAoB;KAC3C,MAAM,YAAY,KAAK,QAAQ,GAAG;KAClC,IAAI,YAAY,GAAG,QAAQ,KAAK;MAAE,QAAQ,KAAK,MAAM,GAAG,SAAS;MAAG,MAAM,KAAK,MAAM,YAAY,CAAC;KAAE,CAAC;IACvG;GACF;GACA,MAAM,aAAa,IAAI,IAAI,MAAM,KAAK,WAAW,OAAO,IAAI,CAAC;GAC7D,MAAM,OAAO,MAAM,IAAI,gBAAgB;IAAC;IAAgB;IAAW;IAAW;GAAM,GAAG,eAAe;GACtG,MAAM,UAAU,KAAK,SAAS,KAAK,KAAK,OAAO,KAAK,MAAM,KAAK,KAAK,OAAO,KAAK,IAAI,KAAA;GACpF,MAAM,SAAS,MAAM,IACnB,gBACA;IAAC;IAAgB;IAAW;IAAW;GAA0B,GACjE,eACF;GACA,MAAM,cAAc,OAAO,SAAS,KAAK,OAAO,OAAO,KAAK,MAAM,KAAK,OAAO,OAAO,KAAK,IAAI;GAC9F,OAAO;IACL,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;IAC3C,GAAI,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY;IACnD;IACA,QAAQ,QAAQ,QAAQ,WAAW,CAAC,WAAW,IAAI,OAAO,IAAI,CAAC;GACjE;EACF;EAEA,MAAM,eAAe,EAAE,gBAAgB,MAAM,SAAS;GAEpD,MAAM,SAAS,MAAM,IAAI,gBAAgB;IAD3B;IAAY;IAAU,GAAI,QAAQ,CAAC,SAAS,IAAI,CAAC;IAAI;GACvB,GAAG,iBAAiB;GAChE,IAAI,OAAO,SAAS,GAAG;GAKvB,IACE,gBAAgB,OAAO,MAAM,KAC7B,CAAE,MAAMA,iBAAAA,QAAG,OAAO,IAAI,CAAC,CAAC,WAChB,YACA,KACR,GACA;IACA,MAAM,MAAM,cAAc;IAC1B;GACF;GACA,MAAM,QAAQ,mBAAmB,MAAM;EACzC;EAEA,MAAM,aAAa,EAAE,gBAAgB,UAAU;GAM7C,QAAO,MADc,IAAI,gBAAgB;IAAC;IAAU;IAAM;GAAM,GAAG,eAAe,EAAA,CACpE,SAAS;EACzB;EACA,gBAAgB;EAEhB,MAAM,kBAAkB,gBAAgB;GACtC,MAAM,SAAS,MAAM,IAAI,gBAAgB;IAAC;IAAY;IAAQ;GAAa,GAAG,eAAe;GAC7F,IAAI,OAAO,SAAS,GAAG,OAAO,CAAC;GAC/B,OAAO,OAAO,OACX,MAAM,IAAI,CAAC,CACX,QAAQ,SAAS,KAAK,WAAW,WAAW,CAAC,CAAC,CAC9C,KAAK,SAAS,KAAK,MAAM,CAAkB,CAAC,CAAC,KAAK,CAAC,CAAC,CACpD,QAAQ,SAAS,SAAS,EAAE;EACjC;EAEA,MAAM,WAAW,MAAM;GACrB,MAAM,SAAS,MAAM,IAAI,MAAM,CAAC,UAAU,aAAa,GAAG,eAAe;GACzE,IAAI,OAAO,SAAS,GAAG,OAAO,CAAC;GAC/B,OAAO,OAAO,OACX,MAAM,IAAI,CAAC,CACX,KAAK,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CACnC,QAAQ,SAAS,SAAS,EAAE;EACjC;EAEA,MAAM,eAAe,KAAK;GACxB,MAAM,SAAS,MAAM,IAAI,KAAK,CAAC,aAAa,iBAAiB,GAAG,eAAe;GAC/E,IAAI,OAAO,SAAS,GAAG,OAAO,KAAA;GAC9B,MAAM,OAAO,OAAO,OAAO,KAAK;GAChC,OAAO,SAAS,KAAK,KAAA,IAAY;EACnC;EAEA,MAAM,cAAc,KAAK;GACvB,MAAM,SAAS,MAAM,IAAI,KAAK;IAAC;IAAa;IAAgB;GAAM,GAAG,eAAe;GACpF,IAAI,OAAO,SAAS,GAAG,OAAO,KAAA;GAC9B,MAAM,SAAS,OAAO,OAAO,KAAK;GAClC,OAAO,WAAW,KAAK,KAAA,IAAY;EACrC;EAEA,MAAM,cAAc,KAAK;GACvB,MAAM,WAAW,MAAM,IACrB,KACA;IAAC;IAAa;IAAgB;IAAwB;GAAa,GACnE,eACF;GACA,IAAI,SAAS,SAAS,GAAG;IACvB,MAAM,SAAS,SAAS,OAAO,KAAK;IACpC,IAAI,WAAW,IAAI,OAAO;GAC5B;GACA,MAAM,SAAS,MAAM,IACnB,KACA;IAAC;IAAgB;IAAW;IAAW;GAA0B,GACjE,eACF;GACA,IAAI,OAAO,SAAS,GAAG;IACrB,MAAM,SAAS,OAAO,OAAO,KAAK;IAClC,IAAI,WAAW,IAAI,OAAO;GAC5B;GACA,MAAM,WAAW,MAAM,IAAI,KAAK;IAAC;IAAgB;IAA4B;GAAc,GAAG,eAAe;GAC7G,IAAI,SAAS,SAAS,GAAG,OAAO,KAAA;GAChC,OAAO,SAAS,OACb,MAAM,IAAI,CAAC,CACX,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,MAAM,SAAS,SAAS,EAAE;EAC/B;EAEA,MAAM,YAAY,EAAE,gBAAgB,QAAQ,WAAW;GAKrD,MAAM,SAAS,MAAM,IAAI,gBAAgB;IAD3B;IAAS;IAAW,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,CAAC,MAAM,OAAO;IAAI;GACzC,GAAG,eAAe;GAC9D,IAAI,OAAO,SAAS,GAAG;GAIvB,MAAM,QAAQ,SAAS,MAAM;EAC/B;CACF;AACF;;;;AC/QA,MAAa,oBAAoB;AACjC,MAAa,oBAAoB;;AAEjC,MAAa,gBAAgB;;AAE7B,MAAa,kBAAkB;AAC/B,MAAa,uBAAuB;;AAEpC,MAAa,uBAAuB;;;;;AAKpC,MAAa,wBAAwB;;;ACwBrC,IAAa,qBAAb,cAAwC,MAAM;CAEjC;CAEA;CACA;CAJX,YACE,MACA,SACA,WACA,UACA;EAGA,MAAM,IAAI,KAAK,IAAI,QAAQ,cAAc,UAAU;EAP1C,KAAA,OAAA;EAEA,KAAA,YAAA;EACA,KAAA,WAAA;EAKT,KAAK,OAAO;CACd;AACF;;AAGA,IAAa,sBAAb,cAAyC,MAAM;CAC7C,YAAY,SAAiB;EAC3B,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;AAEA,SAAgB,eAAe,SAAiB,UAAsC;CACpF,OAAO,IAAI,mBAAmB,mBAAmB,SAAS,OAAO,QAAQ;AAC3E;;;AC9DA,MAAM,kBAAkB;;;;;;;;;;AAWxB,eAAsB,gBAAgB,MAAc,OAA+B;CACjF,MAAM,YAAYC,UAAAA,QAAK,QAAQ,IAAI;CACnC,MAAMC,iBAAAA,QAAG,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;CAC7C,MAAM,YAAYD,UAAAA,QAAK,KAAK,WAAW,IAAIA,UAAAA,QAAK,SAAS,IAAI,EAAE,IAAA,GAAGE,YAAAA,WAAAA,CAAW,EAAE,KAAK;CACpF,MAAMD,iBAAAA,QAAG,UAAU,WAAW,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;CAC9F,MAAMA,iBAAAA,QAAG,OAAO,WAAW,IAAI;AACjC;;;;;;;;AASA,eAAsB,SAAY,MAAsC;CACtE,IAAI;EACF,OAAO,KAAK,MAAM,MAAMA,iBAAAA,QAAG,SAAS,MAAM,MAAM,CAAC;CACnD,QAAQ;EACN;CACF;AACF;;;AC/BA,MAAM,YAAY;AAClB,MAAM,mBAAmB;;;;;;;;;;;AAYzB,eAAsB,mBAAmB,WAAgD;CACvF,IAAI,OAAOE,UAAAA,QAAK,QAAQ,SAAS;CACjC,IAAI,SAASA,UAAAA,QAAK,KAAK,MAAM,MAAM;CACnC,IAAI;CACJ,SACE,IAAI;EACF,OAAO,MAAMC,iBAAAA,QAAG,KAAK,MAAM;EAC3B;CACF,QAAQ;EACN,MAAM,SAASD,UAAAA,QAAK,QAAQ,IAAI;EAChC,IAAI,WAAW,MAAM,OAAO,KAAA;EAC5B,OAAO;EACP,SAASA,UAAAA,QAAK,KAAK,MAAM,MAAM;CACjC;CAEF,IAAI,KAAK,YAAY,GAAG,OAAO;CAC/B,IAAI;CACJ,IAAI;EACF,WAAW,MAAMC,iBAAAA,QAAG,SAAS,QAAQ,MAAM,EAAA,CAAG,KAAK;CACrD,QAAQ;EACN;CACF;CACA,IAAI,CAAC,QAAQ,WAAW,SAAS,GAAG,OAAO,KAAA;CAC3C,MAAM,SAASD,UAAAA,QAAK,QAAQ,MAAM,QAAQ,MAAM,CAAgB,CAAC,CAAC,KAAK,CAAC;CACxE,IAAI;EACF,MAAM,UAAU,MAAMC,iBAAAA,QAAG,SAASD,UAAAA,QAAK,KAAK,QAAQ,WAAW,GAAG,MAAM,EAAA,CAAG,KAAK;EAChF,OAAOA,UAAAA,QAAK,QAAQ,QAAQ,MAAM;CACpC,QAAQ;EAEN,OAAO;CACT;AACF;;AAGA,SAAgB,gBAAgB,MAAsB;CACpD,MAAM,QAAQA,UAAAA,QACX,SAAS,IAAI,CAAC,CACd,YAAY,CAAC,CACb,QAAQ,gBAAgB,GAAG,CAAC,CAC5B,QAAQ,aAAa,EAAE,CAAC,CACxB,MAAM,GAAG,gBAAgB;CAC5B,OAAO,UAAU,KAAK,eAAe;AACvC;;;;;;;;;AAUA,eAAsB,aAAa,MAA+B;CAChE,MAAM,SAAS,MAAM,mBAAmB,IAAI;CAC5C,MAAM,QAAQ,WAAW,KAAA,IAAY,QAAQA,UAAAA,QAAK,QAAQ,IAAI,MAAM,OAAO;CAC3E,QAAA,GAAOE,YAAAA,WAAAA,CAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,SAAS;AAC5E;;AAGA,SAAgB,QAAQ,MAAsB;CAC5C,QAAA,GAAOA,YAAAA,WAAAA,CAAW,QAAQ,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC;AACnE;;;;;;;;;;;;AC1DA,SAAgB,UAAU,UAAkBC,QAAAA,QAAG,QAAQ,GAAW;CAChE,OAAOC,UAAAA,QAAK,MAAA,GAAKC,8BAAAA,gBAAAA,CAAgB,OAAO,GAAG,KAAK;AAClD;;AAGA,SAAgB,cAAc,UAAkBF,QAAAA,QAAG,QAAQ,GAAW;CACpE,OAAOC,UAAAA,QAAK,KAAK,UAAU,OAAO,GAAG,WAAW;AAClD;;;;;;;AAQA,SAAgB,gBAAgB,UAAkBD,QAAAA,QAAG,QAAQ,GAAW;CACtE,OAAOC,UAAAA,QAAK,KAAK,UAAU,OAAO,GAAG,kBAAkB;AACzD;;AAEA,eAAsB,aAAa,gBAAwB,UAAkBD,QAAAA,QAAG,QAAQ,GAAoB;CAC1G,MAAM,KAAK,MAAM,aAAa,cAAc;CAC5C,MAAM,OAAOC,UAAAA,QAAK,KAAK,UAAU,OAAO,GAAG,UAAU;CACrD,MAAM,YAAYA,UAAAA,QAAK,KAAK,MAAM,IAAI,gBAAgB;CACtD,IACE,MAAME,iBAAAA,QAAG,OAAO,SAAS,CAAC,CAAC,WACnB,YACA,KACR,GAEA,OAAO;CACT,IAAI;CACJ,IAAI;EACF,QAAQ,MAAMA,iBAAAA,QAAG,QAAQ,IAAI;CAC/B,QAAQ;EACN,OAAO;CACT;CACA,MAAM,cAAwB,CAAC;CAC/B,KAAK,MAAM,SAAS,MAAM,QAAQ,SAAS,KAAK,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG;EAC3E,MAAM,OAAOF,UAAAA,QAAK,KAAK,MAAM,OAAO,gBAAgB;EACpD,IACE,MAAME,iBAAAA,QAAG,OAAO,IAAI,CAAC,CAAC,WACd,YACA,KACR,GAEA,YAAY,KAAK,IAAI;CACzB;CACA,IAAI,YAAY,WAAW,GAAG,OAAO;CACrC,MAAM,0BAAU,IAAI,IAA4B;CAChD,KAAK,MAAM,QAAQ,aAAa;EAC9B,MAAM,SAAS,MAAM,SAAmD,IAAI;EAC5E,IAAI,QAAQ,YAAA,KAAuC,CAAC,MAAM,QAAQ,OAAO,OAAO,GAAG;EACnF,KAAK,MAAM,SAAS,OAAO,SAAS;GAClC,IACE,OAAO,UAAU,YACjB,UAAU,QACV,EAAE,QAAQ,UACV,OAAO,MAAM,OAAO,YACpB,MAAM,OAAO,IAEb;GACF,MAAM,QAAQ;GACd,MAAM,WAAW,QAAQ,IAAI,MAAM,EAAE;GACrC,IAAI,aAAa,KAAA,KAAa,EAAA,GAACC,UAAAA,kBAAAA,CAAkB,UAAU,KAAK,GAC9D,MAAM,IAAI,MAAM,qDAAqD,MAAM,GAAG,GAAG;GAEnF,QAAQ,IAAI,MAAM,IAAI,KAAK;EAC7B;CACF;CACA,MAAM,YAAY,GAAG,UAAU,IAAA,GAAGC,YAAAA,WAAAA,CAAW,EAAE;CAC/C,MAAM,gBAAgB,WAAW;EAAE,SAAA;EAAkC,SAAS,CAAC,GAAG,QAAQ,OAAO,CAAC;CAAE,CAAC;CACrG,IAAI;EAEF,MAAMF,iBAAAA,QAAG,KAAK,WAAW,SAAS;CACpC,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,UAAU,MAAM;CAChE,UAAU;EACR,MAAMA,iBAAAA,QAAG,GAAG,SAAS;CACvB;CACA,OAAO;AACT;;;ACnGA,MAAa,+BAA+B;AAC5C,MAAa,6BAA6B;;;;;AAK1C,MAAa,4BAA4B;AAEzC,MAAa,6BAA6B;AAyB1C,SAAS,eAAe,OAA+C;CACrE,OAAO,UAAU,YAAY,UAAU;AACzC;AAEA,SAAS,aAAa,OAA6C;CACjE,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO,KAAA;CACxD,MAAM,SAAS;CACf,IAAI,OAAO,YAAA,GAAsC,OAAO,KAAA;CACxD,IAAI,OAAO,OAAO,eAAe,YAAY,OAAO,eAAe,IAAI,OAAO,KAAA;CAC9E,IAAI,OAAO,OAAO,kBAAkB,YAAY,OAAO,kBAAkB,IAAI,OAAO,KAAA;CACpF,IAAI,CAAC,eAAe,OAAO,IAAI,GAAG,OAAO,KAAA;CACzC,IAAI,OAAO,OAAO,SAAS,YAAY,OAAO,SAAS,IAAI,OAAO,KAAA;CAClE,IAAI,OAAO,WAAW,OAAO,MAAM,MAAM,IAAA,OAAgC,OAAO,KAAA;CAChF,IAAI,OAAO,OAAO,WAAW,YAAY,OAAO,WAAW,IAAI,OAAO,KAAA;CACtE,OAAO;AACT;AAEA,SAAgB,2BAA2B,cAAgC,WAAyC;CAClH,IAAI,cAAc,IAAI,MAAM,IAAI,MAAM,sDAAsD;CAC5F,MAAM,2BAAW,IAAI,IAA+B;CACpD,MAAM,cAAc,aAAa,UAAU,4BAA4B,YAAY,YAAY;EAC7F,MAAM,UAAU,aAAa,OAAO;EACpC,IAAI,YAAY,KAAA,GAAW;EAC3B,MAAM,QAAQ,SAAS,IAAI,QAAQ,UAAU,KAAK,CAAC;EACnD,IAAI,MAAM,UAAA,KAAuC,MAAM,MAAM;EAC7D,MAAM,KAAK,OAAO;EAClB,SAAS,IAAI,QAAQ,YAAY,KAAK;CACxC,CAAC;CACD,IAAI,SAAS;CACb,OAAO;EACL,KAAK,iBAAiB,SAAS;GAC7B,IAAI,QAAQ,MAAM,IAAI,MAAM,oCAAoC;GAChE,aAAa,QAAQ,4BAA4B,iBAAiB,OAAO;EAC3E;EACA,QAAQ,YAAY;GAClB,IAAI,QAAQ,OAAO,CAAC;GACpB,MAAM,QAAQ,SAAS,IAAI,UAAU;GACrC,IAAI,UAAU,KAAA,GAAW,OAAO,CAAC;GACjC,SAAS,OAAO,UAAU;GAC1B,OAAO;EACT;EACA,QAAQ;GACN,IAAI,QAAQ;GACZ,SAAS;GACT,YAAY;GACZ,SAAS,MAAM;EACjB;CACF;AACF;AAEA,SAAgB,yBAAyB,OAAiD;CACxF,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CACxD,MAAM,SAAS;CACf,OACE,OAAO,YAAA,KACP,OAAO,OAAO,mBAAmB,YACjC,OAAO,mBAAmB;AAE9B;AAEA,SAAgB,sBAAsB,OAAyB;CAC7D,OACE,OAAO,UAAU,YAAY,UAAU,QAAS,MAAgC,YAAA;AAEpF;;;ACzFA,MAAM,kBAAkB;;AAExB,MAAM,cAAc;AACpB,MAAM,iBAAiB;AACvB,MAAM,kBAAkB;AACxB,MAAM,SAAS;;;;;;;;AASf,SAAgB,WAAW,QAAwB;CACjD,MAAM,OAAO,OACV,YAAY,CAAC,CACb,QAAQ,gBAAgB,GAAG,CAAC,CAC5B,QAAQ,aAAa,EAAE,CAAC,CACxB,MAAM,GAAG,eAAe,CAAC,CACzB,QAAQ,SAAS,EAAE;CACtB,OAAO,SAAS,KAAK,aAAa;AACpC;;;;;;;AAQA,SAAgB,kBAAkB,OAMvB;CACT,MAAM,aAAa,GAAG,MAAM,gBAAgB,IAAI,MAAM;CACtD,OAAO,GAAG,MAAM,cAAc,GAAG,WAAW,GAAG,WAAW,MAAM,MAAM,EAAE,IAAI,MAAM;AACpF;;AAGA,SAAgB,YAAY,OAAoF;CAC9G,IAAI,MAAM,OAAO,KAAK,MAAM,IAAI,OAAO;CAGvC,MAAM,OAAO,MAAM,SAAS,MAAM,WAAW,OAAO,WAAW,MAAM,UAAU,OAAO,WAAW,UAAU;CAC3G,IAAI,MAAM,OAAO,UAAU,MAAM,OAAO,2BAA2B,KAAK,GAAG;AAE7E;;AAGA,SAAgB,YAAY,OAIL;CACrB,IAAI,CAAC,MAAM,QAAQ,OAAO;CAC1B,IAAI,MAAM,WAAW,WAAW,KAAK,MAAM,OAAO,OAAO,KAAA;CAIzD,MAAM,QAAQ,MAAM,WAAW,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,IAAI;CACrD,MAAM,OAAO,MAAM,WAAW,SAAS,KAAK,SAAS,OAAO,MAAM,WAAW,SAAS,EAAE,EAAE,SAAS;CACnG,OAAO,GAAG,OAAO,MAAM,WAAW,MAAM,EAAE,wBAAwB,QAAQ,KAAK;AACjF;;;;;;;;AAeA,eAAsB,UACpB,SACA,OACyB;CACzB,MAAM,UAAoB,CAAC;CAC3B,MAAM,OAAyB,CAAC;CAChC,KAAK,MAAM,UAAU,SAAS;EAC5B,IAAI,OAAO,WAAW,cAAgB,MAAM,MAAM,OAAO,OAAO,IAAI,KAAM,MAAM,MAAM,MAAM,GAAI;GAC9F,KAAK,KAAK,MAAM;GAChB;EACF;EACA,QAAQ,KAAK,OAAO,EAAE;EACtB,KAAK,KAAK;GAAE,GAAG;GAAQ,QAAQ;EAAW,CAAC;CAC7C;CACA,OAAO;EAAE,SAAS;EAAM;CAAQ;AAClC;;;;;;;AA0BA,SAAgB,UAAU,OAKZ;CACZ,MAAM,OAAkB;EAAE,QAAQ,CAAC;EAAG,QAAQ,CAAC;EAAG,WAAW,CAAC;EAAG,WAAW,CAAC;EAAG,cAAc,CAAC;CAAE;CACjG,MAAM,QAAQ,IAAI,IAAI,MAAM,QAAQ,KAAK,WAAW,OAAO,IAAI,CAAC;CAChE,MAAM,SAAS,IAAI,IAAI,MAAM,QAAQ;CACrC,KAAK,MAAM,UAAU,MAAM,SAAS;EAClC,IAAI,OAAO,WAAW,YAAY;EAClC,IAAI,CAAC,OAAO,IAAI,OAAO,IAAI,GAAG;GAC5B,KAAK,OAAO,KAAK,MAAM;GACvB;EACF;EACA,KAAK,MAAM,YAAY,IAAI,OAAO,IAAI,KAAK,CAAC,EAAA,CAAG,SAAS,GAAG;GACzD,KAAK,UAAU,KAAK,MAAM;GAC1B;EACF;EACA,KAAK,OAAO,KAAK,MAAM;CACzB;CACA,KAAK,MAAM,QAAQ,MAAM,UAGvB,IAAI,KAAK,WAAW,GAAG,MAAM,cAAc,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI,GAAG,KAAK,UAAU,KAAK,IAAI;CAE9F,OAAO;AACT;;AAGA,SAAgB,aAAa,MAAuB;CAClD,IAAI,SAAS,MAAM,SAAS,OAAO,KAAK,SAAS,kBAAkB,YAAY,KAAK,IAAI,GAAG,OAAO;CAClG,KAAK,MAAM,aAAa,MAAM;EAC5B,MAAM,OAAO,UAAU,WAAW,CAAC;EACnC,IAAI,OAAO,mBAAmB,SAAS,QAAQ,OAAO;CACxD;CACA,OAAO;AACT;;;AC3JA,MAAM,eAAe;AACrB,MAAM,gBAAgB;AAEtB,SAAS,SAAS,OAAyC;CACzD,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CACxD,MAAM,SAAS;CACf,OACE,OAAO,YAAA,KACP,OAAO,OAAO,OAAO,YACrB,OAAO,OAAO,MACd,OAAO,OAAO,SAAS,YACvB,OAAO,OAAO,WAAW,YACzB,OAAO,OAAO,cAAc;AAEhC;;;;;;AAOA,SAAgB,uBAAuB,MAAqC;CAC1E,OAAO;EACL,MAAM,OAAO;GACX,MAAM,SAAS,MAAM,SAA+B,IAAI;GACxD,IAAI,CAAC,UAAU,OAAO,YAAA,KAAuC,CAAC,MAAM,QAAQ,OAAO,OAAO,GAAG,OAAO,CAAC;GACrG,OAAO,OAAO,QAAQ,OAAO,QAAQ;EACvC;EACA,MAAM,QAAQ,SAAS;GACrB,MAAM,gBAAgB,MAAM;IAAE,SAAA;IAAkC;GAAQ,CAAgC;EAC1G;EACA,MAAM,YAAY,WAAW,QAAQ;GACnC,MAAM,OAAO,GAAG,KAAK;GACrB,MAAMG,iBAAAA,QAAG,MAAMC,UAAAA,QAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;GACtD,MAAM,WAAW,KAAK,IAAI,IAAI;GAC9B,SAAS;IACP,QAAQ,eAAe;IACvB,IAAI;KACF,MAAMD,iBAAAA,QAAG,MAAM,MAAM,EAAE,MAAM,IAAM,CAAC;KACpC;IACF,SAAS,OAAO;KACd,IAAK,MAAgC,SAAS,UAAU,MAAM;KAC9D,IAAI,KAAK,IAAI,KAAK,UAChB,MAAM,IAAI,mBACR,iBACA,6DACA,MACA,8GACF;KACF,OAAA,GAAME,qBAAAA,WAAAA,CAAW,eAAe,KAAA,GAAW,EAAE,OAAO,CAAC;IACvD;GACF;GACA,IAAI;IACF,MAAMF,iBAAAA,QAAG,UACPC,UAAAA,QAAK,KAAK,MAAM,YAAY,GAC5B,KAAK,UAAU;KAAE,KAAK,QAAQ;KAAK,4BAAW,IAAI,KAAK,EAAA,CAAE,YAAY;IAAE,CAAC,GACxE,EAAE,MAAM,IAAM,CAChB;IACA,QAAQ,eAAe;IACvB,OAAO,MAAM,UAAU;GACzB,UAAU;IACR,MAAMD,iBAAAA,QAAG,GAAG,MAAM,EAAE,WAAW,KAAK,CAAC;GACvC;EACF;CACF;AACF;;;AC5DA,MAAM,+BAA+B;AACrC,MAAM,4BAA4B;AAClC,MAAM,2BAA2B;;;;;AAMjC,eAAe,kBAAkB,MAA2C;CAC1E,MAAM,OAAOG,UAAAA,QAAK,KAAK,MAAM,oBAAoB;CACjD,IAAI;CACJ,IAAI;EACF,SAAA,GAASC,QAAAA,KAAAA,CAAK,MAAMC,iBAAAA,QAAG,SAAS,MAAM,MAAM,CAAC,CAAC,EAA6C;CAC7F,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,UAAU,OAAO,KAAA;EAC/D,MAAM,IAAI,mBACR,mBACA,GAAG,qBAAqB,sBAAuB,MAAgB,QAAQ,KACvE,OACA,6BACF;CACF;CACA,MAAM,WAAsB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK;CAC/C,IAAI,CAAC,SAAS,OAAO,YAA+B,OAAO,YAAY,QAAQ,GAC7E,MAAM,IAAI,mBACR,mBACA,GAAG,qBAAqB,kDACxB,OACA,6BACF;CAEF,OAAO,SAAS,QAAQ,YAAY,QAAQ,KAAK,MAAM,EAAE,CAAC,CAAC,KAAK,MAAM,KAAK,KAAA;AAC7E;AAuDA,SAAgB,yBAAyB,MAAkD;CACzF,MAAM,EAAE,QAAQ;CAChB,MAAM,iBAAiB,KAAK;CAC5B,MAAM,MAAM,KAAK,8BAAc,IAAI,KAAK;CACxC,MAAM,8BAAmD;EACvD,IAAI,mBAAmB,KAAA,GACrB,MAAM,IAAI,oBAAoB,8EAA8E;EAC9G,OAAO;CACT;CACA,MAAM,4BAAkD;EACtD,IAAI,KAAK,iBAAiB,KAAA,GACxB,MAAM,IAAI,oBAAoB,0EAA0E;EAC1G,OAAO,KAAK;CACd;CACA,MAAM,4BAAkE,KAAK,kBAAkB;CAC/F,MAAM,+BAAyD;EAC7D,MAAM,WAAW,oBAAoB;EACrC,IAAI,aAAa,KAAA,GACf,MAAM,IAAI,oBAAoB,+EAA+E;EAC/G,OAAO;CACT;CACA,MAAM,QAAQ;EACZ,QAAQ,WAA2B,sBAAsB,CAAC,CAAC,OAAO,OAAO,SAAS;EAClF,SAAS,SACPA,iBAAAA,QAAG,OAAO,IAAI,CAAC,CAAC,WACR,YACA,KACR;CACJ;;;;;;;;CASA,MAAM,UAAU,OAAO,YAA6B;EAClD,MAAM,OAAO,MAAM,IAAI,eAAe,QAAQ,GAAG;EACjD,IAAI,SAAS,KAAA,GACX,MAAM,IAAI,mBACR,oBACA,GAAG,QAAQ,IAAI,mCACf,OACA,sCACF;EAEF,MAAM,QAAQ,uBAAuB,MAAM,aAAa,MAAM,KAAK,OAAO,CAAC;EAC3E,OAAO;GAAE;GAAM;GAAO,SAAS,MAAM,MAAM,KAAK;EAAE;CACpD;CAEA,MAAMC,aAAW,SAAoC,OAA+B;EAClF,MAAM,SAAS,QAAQ,MAAM,UAAU,MAAM,OAAO,EAAE;EACtD,IAAI,WAAW,KAAA,GACb,MAAM,IAAI,mBACR,sBACA,uBAAuB,GAAG,IAC1B,OACA,mCACF;EAEF,OAAO;CACT;;;;;;;;;;;CAYA,MAAM,gBAAgB,SAA0B,QAAwB,WAAyB;EAC/F,IAAI,OAAO,oBAAoB,QAAQ,WAAW;EAClD,IAAI,OAAO,oBAAoB,KAAA,KAAa,CAAC,sBAAsB,CAAC,CAAC,OAAO,OAAO,eAAe,GAAG;EACrG,MAAM,IAAI,mBACR,sBACA,YAAY,OAAO,GAAG,+BACtB,OACA,sCAAsC,OAAO,kCAC/C;CACF;CAEA,MAAM,WACJ,SACA,WACuD;EACvD,IAAI,OAAO,oBAAoB,KAAA,GAC7B,MAAM,IAAI,mBACR,6BACA,YAAY,OAAO,GAAG,+DACtB,OACA,0CACF;EACF,IAAI,QAAQ,cAAc,OAAO,iBAAiB,OAAO;GAAE,WAAW,OAAO;GAAW,OAAO;EAAS;EACxG,IAAI,QAAQ,cAAc,OAAO,WAAW,OAAO;GAAE,WAAW,OAAO;GAAiB,OAAO;EAAQ;EACvG,MAAM,IAAI,mBACR,sBACA,YAAY,OAAO,GAAG,+BACtB,OACA,uCACF;CACF;CAEA,MAAM,mBAAmB,kBAAgC;EACvD,IAAI,CAAC,sBAAsB,CAAC,CAAC,OAAO,aAAa,GAC/C,MAAM,IAAI,mBACR,6BACA,iDACA,OACA,wDACF;CAEJ;CAEA,MAAM,aAAiC;EACrC,MAAM,MAAM,SAAS,SAAS,SAAS;GACrC,MAAM,kBAAkB,QAAQ;GAChC,MAAM,WAAW,oBAAoB,KAAA,IAAY,CAAC,IAAI,EAAE,gBAAgB;GACxE,MAAM,EAAE,MAAM,OAAO,YAAY,MAAM,QAAQ,OAAO;GACtD,MAAM,eAAe,QAAQ,kBAAkB,KAAA,IAAY,KAAA,IAAY,sBAAsB,CAAC,CAAC;GAC/F,IAAI,QAAQ,kBAAkB,KAAA,MAAc,CAAC,gBAAgB,QAAQ,SAAS,KAAA,IAC5E,MAAM,IAAI,mBACR,mBACA,0EACA,OACA,iDACF;GACF,MAAM,WACJ,QAAQ,kBAAkB,KAAA,IAAY,KAAA,IAAY,aAAc,KAAK,QAAQ,eAAe,eAAgB;GAC9G,MAAM,WACJ,aAAa,KAAA,IAAY,KAAA,IAAY,QAAQ,MAAM,WAAW,OAAO,cAAc,SAAS,SAAS;GACvG,IAAI,UAAU;IACZ,MAAM,eAAe,kBAAkB;KACrC,eAAe,cAAc,KAAK,OAAO;KACzC,iBAAiB,gBAAgB,IAAI;KACrC,cAAc,MAAM,aAAa,IAAI;KACrC,QAAQ,QAAQ;KAChB,SAAS,QAAQ,SAAU,SAAS;IACtC,CAAC;IACD,IACE,SAAS,oBAAoB,mBAC7B,SAAS,mBAAmB,QAC5B,SAAS,WAAW,QAAQ,UAC5B,SAAS,SAAS,gBAClB,SAAS,SAAS,UAAU,OAC3B,QAAQ,YAAY,KAAA,KAAa,SAAS,YAAY,QAAQ,WAC/D,CAAE,MAAM,MAAM,OAAO,SAAS,IAAI,KAClC,EAAE,MAAM,IAAI,kBAAkB,IAAI,EAAA,CAAG,SAAS,SAAS,IAAI,KAC1D,MAAM,IAAI,eAAe,SAAS,IAAI,MAAO,SAAS,QACtD,MAAM,IAAI,cAAc,SAAS,IAAI,MAAO,QAAQ,QAErD,MAAM,IAAI,mBACR,mBACA,uDACA,OACA,sEACF;IACF,IAAI,CAAC,sBAAsB,CAAC,CAAC,OAAO,SAAS,SAAS,GAShD;UAAA,MARkB,sBAAsB,CAAC,CAAC,OAAO;MACnD,KAAK,SAAS;MACd,MAAM,QAAQ,QAAQ,QAAQ;MAC9B;MACA,mBAAmB;MACnB,eAAe,QAAQ;MACvB,GAAI,SAAS,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;KACpE,CAAC,EAAA,CACW,cAAc,SAAS,WACjC,MAAM,IAAI,MAAM,qDAAqD;IAAA;IAEzE,MAAM,aAAc,SAAS,QAAQ,eAAgB,eAAgB;IACrE,OAAO;GACT;GACA,MAAM,UAAU,YAAY;IAAE,QAAQ,QAAQ;IAAQ,UAAU;GAAQ,CAAC;GACzE,IAAI,YAAY,KAAA,GACd,MAAM,IAAI,mBAAmB,mBAAmB,SAAS,OAAO,wCAAwC;GAE1G,MAAM,eAAe,QAAQ,SAAS,KAAA,IAAY,KAAA,IAAY,uBAAuB;GAErF,MAAM,QAAQ,MAAM,kBAAkB,IAAI;GAC1C,MAAM,iBAAiB,QAAQ,aAAa;GAC5C,MAAM,KAAK,QAAQ,UAAU,cAAA,GAAaC,YAAAA,WAAAA,CAAW,CAAC;GACtD,IAAI,OAAO,kBAAkB;IAC3B,eAAe,cAAc,KAAK,OAAO;IACzC,iBAAiB,gBAAgB,IAAI;IACrC,cAAc,MAAM,aAAa,IAAI;IACrC,QAAQ,QAAQ;IAChB,SAAS;GACX,CAAC;GACD,IAAI,QAAQ,kBAAkB,KAAA,GAC5B,QAAQ,MAAM,aAAc,QAAQ,QAAQ,eAAe,iBAAkB,IAAI,EAAA,CAAG;GAEtF,MAAM,aAAa,UAAU,QAAQ,KAAA,KAAc,MAAM,MAAM,OAAO,IAAI;GAC1E,IACE,eACC,EAAE,MAAM,IAAI,kBAAkB,IAAI,EAAA,CAAG,SAAS,IAAI,KAAM,MAAM,IAAI,cAAc,IAAI,MAAO,QAAQ,SAEpG,MAAM,IAAI,mBACR,mBACA,uDACA,OACA,0DACF;GACF,IAAI,CAAC,YAAY;IACf,IAAI,gBAAgB;KAClB,MAAM,WAAW,MAAM,IAAI,aAAa,IAAI;KAC5C,MAAM,QAAQ,SAAS,MAAM,MAAM,WAAW,OAAO,SAAS,QAAQ,MAAM;KAM5E,IAAI,EAJF,QAAQ,WAAW,KAAA,IACf,UAAU,KAAA,KAAa,MAAM,iBAAiB,KAAA,IAC9C,UAAU,KAAA,KACV,SAAS,OAAO,MAAM,WAAW,OAAO,WAAW,QAAQ,UAAU,OAAO,SAAS,QAAQ,MAAM,IAEvG,MAAM,IAAI,mBACR,mBACA,OAAO,iBAAiB,KAAA,IACpB,cAAc,QAAQ,OAAO,mCAC7B,cAAc,QAAQ,OAAO,6BAA6B,MAAM,aAAa,IACjF,OACA,2CACF;IACJ,OAEE,KAAK,MAAM,IAAI,aAAa,IAAI,EAAA,CAAG,MAAM,MAAM,WAAW,OAAO,SAAS,QAAQ,MAAM,GACtF,MAAM,IAAI,mBACR,mBACA,cAAc,QAAQ,OAAO,mBAC7B,OACA,sDACF;GAEN;GACA,MAAM,UAAU,iBACZ,QAAQ,WAAW,KAAA,IACjB,QAAQ,SACR,GAAG,QAAQ,OAAO,GAAG,QAAQ,WAC9B,QAAQ,WAAY,MAAM,IAAI,cAAc,IAAI;GACrD,IAAI,YAAY,KAAA,GACd,MAAM,IAAI,mBACR,cACA,2DACA,OACA,oDACF;GAKF,MAAM,kBAA2B,SAAS,QAAQ,YAAY;GAC9D,MAAM,WAAW,YAA6B;IAC5C,IAAI,UAAU,OAAO,6BAA6B,KAAK;IACvD,MAAM,IAAI,eAAe;KAAE,gBAAgB;KAAM;KAAM,OAAO;IAAK,CAAC,CAAC,CAAC,YAAY,KAAA,CAAS;IAE3F,IAAI,kBAAkB,QAAQ,WAAW,KAAA,GAAW,OAAO;IAE3D,OAAO,MADe,IAAI,aAAa;KAAE,gBAAgB;KAAM,QAAQ,QAAQ;IAAO,CAAC,CAAC,CAAC,YAAY,KAAK,IACzF,KAAK,eAAe,QAAQ,OAAO;GACtD;GAEA,SAAS,aAAa,mBAAmB,QAAQ,OAAO,OAAO;GAC/D,IAAI,CAAC,YAAY;IACf,IAAI,gBACF,MAAM,IAAI,oBAAoB;KAC5B,gBAAgB;KAChB;KACA,QAAQ,QAAQ;KAChB,GAAI,QAAQ,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;IACnE,CAAC;SACE,MAAM,IAAI,YAAY;KAAE,gBAAgB;KAAM;KAAM,QAAQ,QAAQ;KAAQ;IAAQ,CAAC;GAC5F;GAKA,IAAI,UAAU,GAEZ,MAAM,IAAI,mBACR,mBACA,wCAAwC,MAHvB,SAAS,KAI1B,OACA,WACI,uEACA,4DACN;GAMF,SAAS,aAAa,mBAAwB;GAC9C,IAAI;GACJ,IAAI;IASF,aAAY,MARU,sBAAsB,CAAC,CAAC,OAAO;KACnD,KAAK;KACL,MAAM,QAAQ,QAAQ,QAAQ;KAC9B,GAAG;KACH,mBAAmB;KACnB,GAAI,SAAS,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;KAClE,GAAI,QAAQ,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,eAAe,QAAQ,cAAc;IACxF,CAAC,EAAA,CACmB;IACpB,IAAI,YAAY,cAAc,SAAS,WACrC,MAAM,IAAI,MAAM,qDAAqD;GACzE,SAAS,OAAO;IACd,MAAM,OAAO,MAAM,SAAS;IAC5B,IAAI,UAAU,GACZ,MAAM,IAAI,mBACR,mBACA,4CAA4C,QAC5C,OACA,WACI,uEACA,4DACN;IAEF,IAAI,iBAAiB,qBACnB,MAAM,IAAI,mBACR,mBACA,GAAG,MAAM,UAAU,QACnB,MACA,kCACF;IAEF,MAAM;GACR;GAEA,MAAM,SAAyB;IAC7B,SAAA;IACA;IACA,QAAQ,QAAQ;IAChB;IACA;IACA,gBAAgB;IAChB;IACA,GAAG;IACH,QAAQ;IACR,WAAW,IAAI,CAAC,CAAC,YAAY;GAC/B;GACA,IAAI;IACF,MAAM,MAAM,QAAQ,CAAC,GAAG,SAAS,MAAM,CAAC;GAC1C,SAAS,OAAO;IAId,MAAM,sBAAsB,CAAC,CAC1B,MAAM,SAAS,CAAC,CAChB,YAAY,KAAA,CAAS;IACxB,MAAM,OAAO,MAAM,SAAS;IAC5B,MAAM,IAAI,mBACR,yBACA,mEAAoE,MAAgB,QAAQ,IAAI,QAChG,MACA,wEACF;GACF;GAGA,IAAI,eAAe;GACnB,IAAI,UAAU,KAAA,GACZ,IAAI;IACF,MAAM,UAAU,sBAAsB;IACtC,IAAI,QAAQ,WAAW,KAAA,GAAW,MAAM,IAAI,MAAM,uCAAuC;IACzF,MAAM,QAAQ,OAAO,WAAW,GAAG,sBAAsB,GAAG,OAAO;IACnE,eAAe;GACjB,SAAS,OAAO;IACd,SAAS,aAAa,iCAAiC,OAAO,KAAK,EAAE,EAAE;GACzE;GAEF,IAAI,QAAQ,SAAS,KAAA,KAAa,iBAAiB,KAAA,GACjD,IAAI;IACF,MAAM,UAAU,MAAM,aAAa,QAAQ;KACzC,cAAc;KACd,MAAM;KACN,QAAQ,eACJ,GAAG,QAAQ,KAAK,0BAA0B,MAAM,4HAChD,QAAQ;KACZ,UAAU;MACR,YAAY,OAAO;MACnB,UAAU;MACV,MAAM,QAAQ;MACd,QAAQ,OAAO;KACjB;IACF,CAAC;IACD,MAAM,YAAY,MAAM,aAAa,iBAAiB,QAAQ,UAAU;IACxE,IAAI,cAAc,YAChB,MAAM,IAAI,mBACR,wBACA,YAAY,OAAO,GAAG,iCAAiC,QAAQ,WAAW,gCAAgC,cAAc,sBAAsB,sBAAsB,uCAAuC,IAC3M,MACA,cAAc,sBACV,+BAA+B,OAAO,GAAG,kFACzC,kBAAkB,QAAQ,WAAW,uDAAuD,OAAO,GAAG,6DAC5G;GAEJ,SAAS,OAAO;IACd,IAAI,iBAAiB,oBAAoB,MAAM;IAC/C,MAAM,IAAI,mBACR,wBACA,YAAY,OAAO,GAAG,0CAA0C,OAAO,KAAK,EAAE,KAC9E,MACA,oBAAoB,OAAO,GAAG,4FAChC;GACF;GAEF,IAAI,QAAQ,kBAAkB,KAAA,GAAW,MAAM,aAAc,SAAS,QAAQ,eAAe,eAAgB;GAC7G,OAAO;EACT;EAEA,MAAM,MAAM,SAAS,IAAI,OAAO;GAC9B,MAAM,EAAE,MAAM,OAAO,YAAY,MAAM,QAAQ,OAAO;GACtD,MAAM,SAASD,UAAQ,SAAS,EAAE;GAClC,aAAa,SAAS,QAAQ,OAAO;GAErC,MAAM,UAAU,YAAY;IAAE;IAAQ,YADlB,MAAM,MAAM,OAAO,OAAO,IAAI,IAAK,MAAM,IAAI,WAAW,OAAO,IAAI,IAAI,CAAC;IAC1C;GAAM,CAAC;GACzD,IAAI,YAAY,KAAA,GACd,MAAM,IAAI,mBAAmB,kBAAkB,SAAS,OAAO,uCAAuC;GAKxG,MAAM,sBAAsB,CAAC,CAAC,MAAM,OAAO,SAAS;GACpD,MAAM,IAAI,eAAe;IAAE,gBAAgB;IAAM,MAAM,OAAO;IAAM;GAAM,CAAC;GAC3E,MAAM,MAAM,QAAQ,QAAQ,QAAQ,UAAU,MAAM,OAAO,EAAE,CAAC;GAC9D,OAAO;EACT;EAEA,MAAM,KAAK,SAAS;GAClB,MAAM,EAAE,OAAO,YAAY,MAAM,QAAQ,OAAO;GAChD,MAAM,UAAU,MAAM,UAAU,SAAS,KAAK;GAC9C,IAAI,QAAQ,QAAQ,SAAS,GAAG,MAAM,MAAM,QAAQ,QAAQ,OAAO;GACnE,OAAO,QAAQ;EACjB;EAEA,MAAM,OAAO,SAAS,IAAI;GACxB,MAAM,EAAE,YAAY,MAAM,QAAQ,OAAO;GACzC,MAAM,SAASA,UAAQ,SAAS,EAAE;GAElC,OAAO;IAAE;IAAQ,YADG,MAAM,MAAM,OAAO,OAAO,IAAI,IAAK,MAAM,IAAI,WAAW,OAAO,IAAI,IAAI,CAAC;GAChE;EAC9B;EAEA,MAAM,MAAM,SAAS,IAAI,SAAS;GAChC,MAAM,EAAE,MAAM,YAAY,MAAM,QAAQ,OAAO;GAC/C,MAAM,SAASA,UAAQ,SAAS,EAAE;GAClC,aAAa,SAAS,QAAQ,OAAO;GAIrC,MAAM,cAAc,MAAM,IAAI,WAAW,IAAI;GAC7C,IAAI,YAAY,SAAS,GACvB,MAAM,IAAI,mBACR,kBACA,2BAA2B,OAAO,YAAY,MAAM,EAAE,wBAAwB,YAAY,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,IAClH,OACA,4CACF;GAEF,MAAM,IAAI,YAAY;IACpB,gBAAgB;IAChB,QAAQ,OAAO;IACf,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;GAC7C,CAAC;GACD,OAAO;EACT;;EAGA,MAAM,KAAK,SAAS,IAAI,SAAS;GAC/B,IAAI,OAAO,WAAW,SAAS,MAAM,IAAA,OACnC,MAAM,IAAI,mBACR,qBACA,4BAA4B,OAAO,0BAA0B,EAAE,UAC/D,OACA,yBACF;GAEF,MAAM,EAAE,YAAY,MAAM,QAAQ,OAAO;GACzC,MAAM,SAASA,UAAQ,SAAS,EAAE;GAClC,MAAM,OAAO,QAAQ,SAAS,MAAM;GACpC,gBAAgB,KAAK,SAAS;GAC9B,MAAM,0BAAS,IAAI,KAAK,EAAA,CAAE,YAAY;GACtC,MAAM,WAAW,oBAAoB;GACrC,IAAI,aAAa,KAAA,GAAW;IAC1B,MAAM,OAAO,KAAK,UAAU,WAAW,4BAA4B;IACnE,MAAM,UAAU,MAAM,SAAS,QAAQ;KACrC,cAAc,KAAK;KACnB;KACA,QACE,KAAK,UAAU,WACX,+BAA+B,OAAO,GAAG,OAAO,YAChD,wBAAwB,OAAO,GAAG,OAAO;KAC/C,UAAU;MAAE,YAAY,OAAO;MAAI,UAAU,KAAK;MAAO,MAAM;MAAS;KAAO;IACjF,CAAC;IACD,MAAM,YAAY,MAAM,SAAS,iBAAiB,QAAQ,UAAU;IACpE,IAAI,cAAc,YAChB,MAAM,IAAI,mBACR,2BACA,YAAY,OAAO,GAAG,8BAA8B,QAAQ,WAAW,kBAAkB,cAAc,sBAAsB,sBAAsB,uCAAuC,IAC1L,MACA,cAAc,sBACV,gEAAgE,QAAQ,WAAW,qCACnF,kBAAkB,QAAQ,WAAW,qGAC3C;IAEF;GACF;GACA,oBAAoB,CAAC,CAAC,KAAK,KAAK,WAAW;IACzC,SAAS;IACT,YAAY,OAAO;IAEnB,eAAe,QAAQ;IACvB,MAAM,KAAK;IACX,MAAM;IACN;GACF,CAAC;EACH;EAEA,MAAM,SAAS,SAAS,IAAI;GAC1B,MAAM,EAAE,YAAY,MAAM,QAAQ,OAAO;GACzC,MAAM,SAASA,UAAQ,SAAS,EAAE;GAClC,MAAM,OAAO,QAAQ,SAAS,MAAM;GACpC,MAAM,WAAW,oBAAoB;GACrC,IAAI,aAAa,KAAA,GAAW,OAAO,oBAAoB,CAAC,CAAC,QAAQ,OAAO,EAAE;GAC1E,MAAM,WAAW,MAAM,SAAS,MAAM;IAAE,UAAU;IAAO,UAAU,EAAE,YAAY,OAAO,GAAG;GAAE,CAAC,EAAA,CAAG,QAC9F,UACC,MAAM,cAAc,KAAK,cACxB,MAAM,UAAU,cAAc,MAAM,UAAU,yBAC9C,KAAK,UAAU,WACZ,MAAM,SAAS,2BACf,MAAM,SAAS,6BAA6B,MAAM,SAAS,6BACnE;GACA,KAAK,MAAM,SAAS,SAAS,MAAM,SAAS,QAAQ,MAAM,UAAU;GACpE,OAAO,QAAQ,KAAK,WAAW;IAC7B,SAAS;IACT,YAAY,OAAO;IACnB,eAAe,MAAM;IACrB,MAAM,KAAK,UAAU,WAAY,UAAqB;IACtD,MACE,MAAM,UAAU,sBACZ,2DAA2D,MAAM,SAAS,QAAQ,MAAM,WACvF,MAAM,SAAS,QAAQ,MAAM;IACpC,QAAQ,MAAM,SAAS,UAAU;GACnC,EAAE;EACJ;EAEA,MAAM,MAAM,SAAS,QAAQ;GAC3B,MAAM,EAAE,MAAM,OAAO,YAAY,MAAM,QAAQ,OAAO;GACtD,MAAM,aAAa,MAAM,UAAU,SAAS,KAAK;GACjD,MAAM,WAAW,MAAM,IAAI,kBAAkB,IAAI;GACjD,MAAM,8BAAc,IAAI,IAA+B;GACvD,KAAK,MAAM,UAAU,WAAW,SAC9B,IAAI,OAAO,WAAW,cAAe,MAAM,MAAM,OAAO,OAAO,IAAI,GACjE,YAAY,IAAI,OAAO,MAAM,MAAM,IAAI,WAAW,OAAO,IAAI,CAAC;GAGlE,MAAM,OAAO,UAAU;IACrB,SAAS,WAAW;IACpB;IACA,eAAe,cAAc,KAAK,OAAO;IACzC;GACF,CAAC;GACD,IAAI,QAAQ;IACV,MAAM,MAAM,QAAQ,WAAW,OAAO;IACtC,OAAO;GACT;GACA,KAAK,MAAM,UAAU,KAAK,QACxB,MAAM,IAAI,eAAe;IAAE,gBAAgB;IAAM,MAAM,OAAO;IAAM,OAAO;GAAM,CAAC;GAKpF,KAAK,MAAM,UAAU,CAAC,GAAG,KAAK,QAAQ,GAAG,KAAK,MAAM,GAElD,IAAI,CAAC,MADiB,IAAI,aAAa;IAAE,gBAAgB;IAAM,QAAQ,OAAO;GAAO,CAAC,CAAC,CAAC,YAAY,KAAK,GAC3F,KAAK,aAAa,KAAK,OAAO,MAAM;GAEpD,MAAM,UAAU,IAAI,IAAI,CAAC,GAAG,KAAK,QAAQ,GAAG,KAAK,MAAM,CAAC,CAAC,KAAK,WAAW,OAAO,EAAE,CAAC;GACnF,MAAM,MAAM,QAAQ,WAAW,QAAQ,QAAQ,WAAW,CAAC,QAAQ,IAAI,OAAO,EAAE,CAAC,CAAC;GAClF,OAAO;EACT;CACF;CACA,MAAM,SAAS,OAAU,SAA0B,WAA6B,WAAqC;EACnH,IAAI;GACF,MAAM,EAAE,UAAU,MAAM,QAAQ,OAAO;GACvC,OAAO,MAAM,MAAM,YAAY,WAAW,MAAM;EAClD,SAAS,OAAO;GACd,IAAI,QAAQ,WAAW,EAAE,iBAAiB,qBACxC,MAAM,IAAI,mBACR,mBACA,yCACA,OACA,6CACF;GACF,IAAI;IAAC;IAAW;IAAU;IAAS;GAAQ,CAAC,CAAC,SAAS,OAAQ,MAAgC,IAAI,CAAC,GACjG,MAAM,IAAI,mBACR,yBACA,0CACA,MACA,mDACF;GACF,MAAM;EACR;CACF;CAGA,OAAO;EACL,GAAG;EACH,QAAQ,SAAS,SAAS,YAAY;GACpC,IAAI,mBAAmB,KAAA,GACrB,OAAO,QAAQ,OACb,IAAI,mBACF,mBACA,+CACA,MACA,yEACF,CACF;GAEF,IAAI,CAAC,aAAa,QAAQ,MAAM,KAAM,QAAQ,YAAY,KAAA,KAAa,CAAC,aAAa,QAAQ,OAAO,GAClG,OAAO,QAAQ,OACb,IAAI,mBAAmB,mBAAmB,oCAAoC,OAAO,oBAAoB,CAC3G;GACF,IAAI,QAAQ,kBAAkB,KAAA,KAAa,QAAQ,cAAc,KAAA,GAC/D,OAAO,QAAQ,OACb,IAAI,mBACF,mBACA,2DACA,OACA,iDACF,CACF;GACF,OAAO,OAAO,eAAe,WAAW,MAAM,SAAS,SAAS,OAAO,GAAG,SAAS,MAAM;EAC3F;EACA,QAAQ,SAAS,IAAI,UAAU,OAAO,eAAe,WAAW,MAAM,SAAS,IAAI,KAAK,CAAC;EACzF,OAAO,YAAY,OAAO,eAAe,WAAW,KAAK,OAAO,CAAC;EACjE,QAAQ,SAAS,IAAI,YAAY,OAAO,eAAe,WAAW,MAAM,SAAS,IAAI,OAAO,CAAC;EAC7F,QAAQ,SAAS,WAAW,OAAO,eAAe,WAAW,MAAM,SAAS,MAAM,CAAC;CACrF;AACF"}
@@ -1,5 +1,5 @@
1
1
  import { execFile } from "node:child_process";
2
- import fs from "node:fs";
2
+ import fs from "node:fs/promises";
3
3
  import { createHash, randomUUID } from "node:crypto";
4
4
  import path from "node:path";
5
5
  import { load } from "js-yaml";
@@ -175,7 +175,7 @@ function createWorktreeGit() {
175
175
  path
176
176
  ], REMOVE_TIMEOUT_MS);
177
177
  if (result.code === 0) return;
178
- if (missingWorktree(result.stderr) && !fs.existsSync(path)) {
178
+ if (missingWorktree(result.stderr) && !await fs.access(path).then(() => true, () => false)) {
179
179
  await prune(repositoryRoot);
180
180
  return;
181
181
  }
@@ -313,12 +313,12 @@ const OWNER_ONLY_FILE = 384;
313
313
  * record in it. Writing beside the target and renaming makes the swap atomic on
314
314
  * the same filesystem, so a reader sees either the old file or the new one.
315
315
  */
316
- function writeJsonAtomic(file, value) {
316
+ async function writeJsonAtomic(file, value) {
317
317
  const directory = path.dirname(file);
318
- fs.mkdirSync(directory, { recursive: true });
319
- const temporary = path.join(directory, `.${path.basename(file)}.${String(process.pid)}.tmp`);
320
- fs.writeFileSync(temporary, `${JSON.stringify(value, null, 2)}\n`, { mode: OWNER_ONLY_FILE });
321
- fs.renameSync(temporary, file);
318
+ await fs.mkdir(directory, { recursive: true });
319
+ const temporary = path.join(directory, `.${path.basename(file)}.${randomUUID()}.tmp`);
320
+ await fs.writeFile(temporary, `${JSON.stringify(value, null, 2)}\n`, { mode: OWNER_ONLY_FILE });
321
+ await fs.rename(temporary, file);
322
322
  }
323
323
  /**
324
324
  * Reads JSON, treating every failure as absent.
@@ -327,9 +327,9 @@ function writeJsonAtomic(file, value) {
327
327
  * here: there is nothing to act on. Distinguishing them would only offer a
328
328
  * choice no caller wants to make.
329
329
  */
330
- function readJson(file) {
330
+ async function readJson(file) {
331
331
  try {
332
- return JSON.parse(fs.readFileSync(file, "utf8"));
332
+ return JSON.parse(await fs.readFile(file, "utf8"));
333
333
  } catch {
334
334
  return;
335
335
  }
@@ -348,12 +348,12 @@ const MAX_LABEL_LENGTH = 32;
348
348
  * the registry is per repository and must be found from inside a worktree too.
349
349
  * A session may run in a subdirectory, so the nearest enclosing checkout is used.
350
350
  */
351
- function gitCommonDirectory(directory) {
351
+ async function gitCommonDirectory(directory) {
352
352
  let root = path.resolve(directory);
353
353
  let marker = path.join(root, ".git");
354
354
  let stat;
355
355
  for (;;) try {
356
- stat = fs.statSync(marker);
356
+ stat = await fs.stat(marker);
357
357
  break;
358
358
  } catch {
359
359
  const parent = path.dirname(root);
@@ -364,14 +364,14 @@ function gitCommonDirectory(directory) {
364
364
  if (stat.isDirectory()) return marker;
365
365
  let pointer;
366
366
  try {
367
- pointer = fs.readFileSync(marker, "utf8").trim();
367
+ pointer = (await fs.readFile(marker, "utf8")).trim();
368
368
  } catch {
369
369
  return;
370
370
  }
371
371
  if (!pointer.startsWith("gitdir:")) return void 0;
372
372
  const gitDir = path.resolve(root, pointer.slice(7).trim());
373
373
  try {
374
- const common = fs.readFileSync(path.join(gitDir, "commondir"), "utf8").trim();
374
+ const common = (await fs.readFile(path.join(gitDir, "commondir"), "utf8")).trim();
375
375
  return path.resolve(gitDir, common);
376
376
  } catch {
377
377
  return gitDir;
@@ -390,8 +390,8 @@ function repositoryLabel(root) {
390
390
  * registry. Falling back to the path keeps a non-repository directory usable
391
391
  * instead of failing, though nothing here should reach that case.
392
392
  */
393
- function repositoryId(root) {
394
- const common = gitCommonDirectory(root);
393
+ async function repositoryId(root) {
394
+ const common = await gitCommonDirectory(root);
395
395
  const token = common === void 0 ? `root:${path.resolve(root)}` : `git:${common}`;
396
396
  return createHash("sha256").update(token).digest("hex").slice(0, ID_LENGTH);
397
397
  }
@@ -427,22 +427,26 @@ function credentialsFile(homeDir = os.homedir()) {
427
427
  return path.join(poGitRoot(homeDir), "credentials.json");
428
428
  }
429
429
  /** One registry file per repository, keyed by the shared git directory. */
430
- function registryFile(repositoryRoot, homeDir = os.homedir()) {
431
- const id = repositoryId(repositoryRoot);
430
+ async function registryFile(repositoryRoot, homeDir = os.homedir()) {
431
+ const id = await repositoryId(repositoryRoot);
432
432
  const root = path.join(poGitRoot(homeDir), "registry");
433
433
  const canonical = path.join(root, id, "worktrees.json");
434
- if (fs.existsSync(canonical)) return canonical;
434
+ if (await fs.access(canonical).then(() => true, () => false)) return canonical;
435
435
  let names;
436
436
  try {
437
- names = fs.readdirSync(root);
437
+ names = await fs.readdir(root);
438
438
  } catch {
439
439
  return canonical;
440
440
  }
441
- const legacyFiles = names.filter((entry) => entry.endsWith(`--${id}`)).sort().map((entry) => path.join(root, entry, "worktrees.json")).filter((file) => fs.existsSync(file));
441
+ const legacyFiles = [];
442
+ for (const entry of names.filter((name) => name.endsWith(`--${id}`)).sort()) {
443
+ const file = path.join(root, entry, "worktrees.json");
444
+ if (await fs.access(file).then(() => true, () => false)) legacyFiles.push(file);
445
+ }
442
446
  if (legacyFiles.length === 0) return canonical;
443
447
  const entries = /* @__PURE__ */ new Map();
444
448
  for (const file of legacyFiles) {
445
- const legacy = readJson(file);
449
+ const legacy = await readJson(file);
446
450
  if (legacy?.version !== 1 || !Array.isArray(legacy.entries)) continue;
447
451
  for (const value of legacy.entries) {
448
452
  if (typeof value !== "object" || value === null || !("id" in value) || typeof value.id !== "string" || value.id === "") continue;
@@ -453,16 +457,16 @@ function registryFile(repositoryRoot, homeDir = os.homedir()) {
453
457
  }
454
458
  }
455
459
  const temporary = `${canonical}.${randomUUID()}.migration`;
456
- writeJsonAtomic(temporary, {
460
+ await writeJsonAtomic(temporary, {
457
461
  version: 1,
458
462
  entries: [...entries.values()]
459
463
  });
460
464
  try {
461
- fs.linkSync(temporary, canonical);
465
+ await fs.link(temporary, canonical);
462
466
  } catch (error) {
463
467
  if (error.code !== "EEXIST") throw error;
464
468
  } finally {
465
- fs.rmSync(temporary);
469
+ await fs.rm(temporary);
466
470
  }
467
471
  return canonical;
468
472
  }
@@ -581,18 +585,22 @@ function refuseClose(input) {
581
585
  * uncommitted work, so losing the record would lose the only pointer to it.
582
586
  * Deletion is always a separate, named decision.
583
587
  */
584
- function reconcile(records, probe) {
588
+ async function reconcile(records, probe) {
585
589
  const changed = [];
590
+ const next = [];
591
+ for (const record of records) {
592
+ if (record.status === "orphaned" || await probe.exists(record.path) && probe.alive(record)) {
593
+ next.push(record);
594
+ continue;
595
+ }
596
+ changed.push(record.id);
597
+ next.push({
598
+ ...record,
599
+ status: "orphaned"
600
+ });
601
+ }
586
602
  return {
587
- records: records.map((record) => {
588
- if (record.status === "orphaned") return record;
589
- if (!(!probe.exists(record.path) || !probe.alive(record))) return record;
590
- changed.push(record.id);
591
- return {
592
- ...record,
593
- status: "orphaned"
594
- };
595
- }),
603
+ records: next,
596
604
  changed
597
605
  };
598
606
  }
@@ -652,25 +660,25 @@ function isRecord(value) {
652
660
  */
653
661
  function createWorktreeRegistry(file) {
654
662
  return {
655
- list() {
656
- const parsed = readJson(file);
663
+ async list() {
664
+ const parsed = await readJson(file);
657
665
  if (!parsed || parsed.version !== 1 || !Array.isArray(parsed.entries)) return [];
658
666
  return parsed.entries.filter(isRecord);
659
667
  },
660
- replace(entries) {
661
- writeJsonAtomic(file, {
668
+ async replace(entries) {
669
+ await writeJsonAtomic(file, {
662
670
  version: 1,
663
671
  entries
664
672
  });
665
673
  },
666
674
  async transaction(operation, signal) {
667
675
  const lock = `${file}.lock`;
668
- fs.mkdirSync(path.dirname(file), { recursive: true });
676
+ await fs.mkdir(path.dirname(file), { recursive: true });
669
677
  const deadline = Date.now() + LOCK_WAIT_MS;
670
678
  for (;;) {
671
679
  signal?.throwIfAborted();
672
680
  try {
673
- fs.mkdirSync(lock, { mode: 448 });
681
+ await fs.mkdir(lock, { mode: 448 });
674
682
  break;
675
683
  } catch (error) {
676
684
  if (error.code !== "EEXIST") throw error;
@@ -679,14 +687,14 @@ function createWorktreeRegistry(file) {
679
687
  }
680
688
  }
681
689
  try {
682
- fs.writeFileSync(path.join(lock, "owner.json"), JSON.stringify({
690
+ await fs.writeFile(path.join(lock, "owner.json"), JSON.stringify({
683
691
  pid: process.pid,
684
692
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
685
693
  }), { mode: 384 });
686
694
  signal?.throwIfAborted();
687
695
  return await operation();
688
696
  } finally {
689
- fs.rmSync(lock, { recursive: true });
697
+ await fs.rm(lock, { recursive: true });
690
698
  }
691
699
  }
692
700
  };
@@ -700,13 +708,13 @@ const GIT_WORKTREE_REPORT_KIND = "git.worktree.report";
700
708
  * The repository's worktree setup as one shell command, or undefined when it asks for none.
701
709
  * Read from the checkout the spawn starts in, so an uncommitted edit applies at once.
702
710
  */
703
- function readWorktreeSetup(root) {
711
+ async function readWorktreeSetup(root) {
704
712
  const file = path.join(root, WORKTREE_CONFIG_FILE);
705
- if (!fs.existsSync(file)) return void 0;
706
713
  let setup;
707
714
  try {
708
- setup = load(fs.readFileSync(file, "utf8"))?.setup;
715
+ setup = load(await fs.readFile(file, "utf8"))?.setup;
709
716
  } catch (error) {
717
+ if (error.code === "ENOENT") return void 0;
710
718
  throw new PoGitExpectedError("invalid_request", `${WORKTREE_CONFIG_FILE} is not valid YAML (${error.message}).`, false, "Fix the file and try again.");
711
719
  }
712
720
  const commands = [setup ?? []].flat();
@@ -733,7 +741,7 @@ function createWorktreeOperations(deps) {
733
741
  };
734
742
  const probe = {
735
743
  alive: (record) => requireSessionService().isLive(record.sessionId),
736
- exists: (path) => fs.existsSync(path)
744
+ exists: (path) => fs.access(path).then(() => true, () => false)
737
745
  };
738
746
  /**
739
747
  * Everything an action needs about the repository it is acting on.
@@ -745,11 +753,11 @@ function createWorktreeOperations(deps) {
745
753
  const resolve = async (context) => {
746
754
  const root = await git.repositoryRoot(context.cwd);
747
755
  if (root === void 0) throw new PoGitExpectedError("not_a_repository", `${context.cwd} is not inside a git repository.`, false, "Run this from a repository checkout.");
748
- const store = createWorktreeRegistry(registryFile(root, deps.homeDir));
756
+ const store = createWorktreeRegistry(await registryFile(root, deps.homeDir));
749
757
  return {
750
758
  root,
751
759
  store,
752
- records: store.list()
760
+ records: await store.list()
753
761
  };
754
762
  };
755
763
  const require = (records, id) => {
@@ -800,11 +808,11 @@ function createWorktreeOperations(deps) {
800
808
  const expectedPath = worktreeDirectory({
801
809
  worktreesRoot: worktreesRoot(deps.homeDir),
802
810
  repositoryLabel: repositoryLabel(root),
803
- repositoryId: repositoryId(root),
811
+ repositoryId: await repositoryId(root),
804
812
  branch: request.branch,
805
813
  shortId: shortId(reserved.sessionId)
806
814
  });
807
- if (existing.parentSessionId !== parentSessionId || existing.repositoryRoot !== root || existing.branch !== request.branch || existing.path !== expectedPath || existing.path !== reserved?.cwd || request.baseRef !== void 0 && existing.baseRef !== request.baseRef || !fs.existsSync(existing.path) || !(await git.listWorktreePaths(root)).includes(existing.path) || await git.repositoryRoot(existing.path) !== existing.path || await git.currentBranch(existing.path) !== request.branch) throw new PoGitExpectedError("invalid_request", "The reserved checkout no longer matches this setup.", false, "Inspect the existing branch and checkout; they will not be replaced.");
815
+ if (existing.parentSessionId !== parentSessionId || existing.repositoryRoot !== root || existing.branch !== request.branch || existing.path !== expectedPath || existing.path !== reserved?.cwd || request.baseRef !== void 0 && existing.baseRef !== request.baseRef || !await probe.exists(existing.path) || !(await git.listWorktreePaths(root)).includes(existing.path) || await git.repositoryRoot(existing.path) !== existing.path || await git.currentBranch(existing.path) !== request.branch) throw new PoGitExpectedError("invalid_request", "The reserved checkout no longer matches this setup.", false, "Inspect the existing branch and checkout; they will not be replaced.");
808
816
  if (!requireSessionService().isLive(existing.sessionId)) {
809
817
  if ((await requireSessionService().create({
810
818
  cwd: existing.path,
@@ -824,18 +832,18 @@ function createWorktreeOperations(deps) {
824
832
  });
825
833
  if (refusal !== void 0) throw new PoGitExpectedError("worktree_exists", refusal, false, "Pick another branch name, or close it.");
826
834
  const taskDelivery = request.task === void 0 ? void 0 : requireSessionDelivery();
827
- const setup = readWorktreeSetup(root);
835
+ const setup = await readWorktreeSetup(root);
828
836
  const existingBranch = request.checkout === "existing";
829
837
  const id = shortId(reserved?.sessionId ?? randomUUID());
830
838
  let path = worktreeDirectory({
831
839
  worktreesRoot: worktreesRoot(deps.homeDir),
832
840
  repositoryLabel: repositoryLabel(root),
833
- repositoryId: repositoryId(root),
841
+ repositoryId: await repositoryId(root),
834
842
  branch: request.branch,
835
843
  shortId: id
836
844
  });
837
845
  if (request.reservationId !== void 0) path = (await reservations.prepare(request.reservationId, parentSessionId, path)).cwd;
838
- const recovering = reserved?.cwd !== void 0 && fs.existsSync(path);
846
+ const recovering = reserved?.cwd !== void 0 && await probe.exists(path);
839
847
  if (recovering && (!(await git.listWorktreePaths(root)).includes(path) || await git.currentBranch(path) !== request.branch)) throw new PoGitExpectedError("invalid_request", "The reserved checkout no longer matches this setup.", false, "Inspect the existing directory; it will not be replaced.");
840
848
  if (!recovering) {
841
849
  if (existingBranch) {
@@ -907,7 +915,7 @@ function createWorktreeOperations(deps) {
907
915
  createdAt: now().toISOString()
908
916
  };
909
917
  try {
910
- store.replace([...records, record]);
918
+ await store.replace([...records, record]);
911
919
  } catch (error) {
912
920
  await requireSessionService().close(sessionId).catch(() => void 0);
913
921
  const kept = await rollback();
@@ -949,7 +957,7 @@ function createWorktreeOperations(deps) {
949
957
  requireOwner(context, record, "close");
950
958
  const refusal = refuseClose({
951
959
  record,
952
- dirtyFiles: fs.existsSync(record.path) ? await git.dirtyFiles(record.path) : [],
960
+ dirtyFiles: await probe.exists(record.path) ? await git.dirtyFiles(record.path) : [],
953
961
  force
954
962
  });
955
963
  if (refusal !== void 0) throw new PoGitExpectedError("worktree_dirty", refusal, false, "Commit the work, or pass force: true.");
@@ -959,13 +967,13 @@ function createWorktreeOperations(deps) {
959
967
  path: record.path,
960
968
  force
961
969
  });
962
- store.replace(records.filter((entry) => entry.id !== id));
970
+ await store.replace(records.filter((entry) => entry.id !== id));
963
971
  return record;
964
972
  },
965
973
  async list(context) {
966
974
  const { store, records } = await resolve(context);
967
- const outcome = reconcile(records, probe);
968
- if (outcome.changed.length > 0) store.replace(outcome.records);
975
+ const outcome = await reconcile(records, probe);
976
+ if (outcome.changed.length > 0) await store.replace(outcome.records);
969
977
  return outcome.records;
970
978
  },
971
979
  async status(context, id) {
@@ -973,7 +981,7 @@ function createWorktreeOperations(deps) {
973
981
  const record = require(records, id);
974
982
  return {
975
983
  record,
976
- dirtyFiles: fs.existsSync(record.path) ? await git.dirtyFiles(record.path) : []
984
+ dirtyFiles: await probe.exists(record.path) ? await git.dirtyFiles(record.path) : []
977
985
  };
978
986
  },
979
987
  async merge(context, id, message) {
@@ -1046,10 +1054,10 @@ function createWorktreeOperations(deps) {
1046
1054
  },
1047
1055
  async prune(context, dryRun) {
1048
1056
  const { root, store, records } = await resolve(context);
1049
- const reconciled = reconcile(records, probe);
1057
+ const reconciled = await reconcile(records, probe);
1050
1058
  const gitPaths = await git.listWorktreePaths(root);
1051
1059
  const dirtyByPath = /* @__PURE__ */ new Map();
1052
- for (const record of reconciled.records) if (record.status === "orphaned" && fs.existsSync(record.path)) dirtyByPath.set(record.path, await git.dirtyFiles(record.path));
1060
+ for (const record of reconciled.records) if (record.status === "orphaned" && await probe.exists(record.path)) dirtyByPath.set(record.path, await git.dirtyFiles(record.path));
1053
1061
  const plan = planPrune({
1054
1062
  records: reconciled.records,
1055
1063
  gitPaths,
@@ -1057,7 +1065,7 @@ function createWorktreeOperations(deps) {
1057
1065
  dirtyByPath
1058
1066
  });
1059
1067
  if (dryRun) {
1060
- store.replace(reconciled.records);
1068
+ await store.replace(reconciled.records);
1061
1069
  return plan;
1062
1070
  }
1063
1071
  for (const record of plan.remove) await git.removeWorktree({
@@ -1070,7 +1078,7 @@ function createWorktreeOperations(deps) {
1070
1078
  branch: record.branch
1071
1079
  }).catch(() => false)) plan.keptBranches.push(record.branch);
1072
1080
  const dropped = new Set([...plan.remove, ...plan.forget].map((record) => record.id));
1073
- store.replace(reconciled.records.filter((record) => !dropped.has(record.id)));
1081
+ await store.replace(reconciled.records.filter((record) => !dropped.has(record.id)));
1074
1082
  return plan;
1075
1083
  }
1076
1084
  };
@@ -1106,4 +1114,4 @@ function createWorktreeOperations(deps) {
1106
1114
  //#endregion
1107
1115
  export { READ_TIMEOUT_MS as C, runGit as E, NETWORK_TIMEOUT_MS as S, createWorktreeGit as T, GIT_AUTH_PATH as _, GIT_WORKTREE_LIFECYCLE_EVENT as a, GIT_REVIEW_PATH as b, isWorktreeLifecycleEvent as c, registryFile as d, readJson as f, invalidRequest as g, PoGitExpectedError as h, GIT_SESSION_CHANGED_EVENT as i, credentialsFile as l, HubUnavailableError as m, createWorktreeRegistry as n, createWorktreeMessageInbox as o, writeJsonAtomic as p, validRefName as r, isSessionChangedEvent as s, createWorktreeOperations as t, poGitRoot as u, GIT_BRANCHES_PATH as v, REBASE_TIMEOUT_MS as w, GIT_SESSIONS_PATH as x, GIT_REVIEW_FILE_PATH as y };
1108
1116
 
1109
- //# sourceMappingURL=worktreeOperations-BqLLypS5.mjs.map
1117
+ //# sourceMappingURL=worktreeOperations-CP2lYxrI.mjs.map