@agimon-ai/doompi-git 0.0.1-alpha.4 → 0.0.1-alpha.40

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.
Files changed (180) hide show
  1. package/README.md +33 -1
  2. package/dist/apiContracts.cjs +387 -0
  3. package/dist/apiContracts.cjs.map +1 -0
  4. package/dist/apiContracts.d.mts +53 -0
  5. package/dist/apiContracts.d.mts.map +1 -0
  6. package/dist/apiContracts.mjs +382 -0
  7. package/dist/apiContracts.mjs.map +1 -0
  8. package/dist/extensions/pi.cjs +105 -1
  9. package/dist/extensions/pi.cjs.map +1 -0
  10. package/dist/extensions/pi.d.mts +6 -2
  11. package/dist/extensions/pi.d.mts.map +1 -0
  12. package/dist/extensions/pi.mjs +100 -1
  13. package/dist/extensions/pi.mjs.map +1 -0
  14. package/dist/extensions/server.cjs +1828 -0
  15. package/dist/extensions/server.cjs.map +1 -0
  16. package/dist/extensions/server.d.mts +5 -0
  17. package/dist/extensions/server.d.mts.map +1 -0
  18. package/dist/extensions/server.mjs +1820 -0
  19. package/dist/extensions/server.mjs.map +1 -0
  20. package/dist/extensions/web.mjs +2619 -0
  21. package/dist/extensions/web.mjs.map +1 -0
  22. package/dist/gitDependencies-CtVubYvU.mjs +22 -0
  23. package/dist/gitDependencies-CtVubYvU.mjs.map +1 -0
  24. package/dist/gitDependencies-Dqsz2HjK.cjs +33 -0
  25. package/dist/gitDependencies-Dqsz2HjK.cjs.map +1 -0
  26. package/dist/index-D79MSCee.d.mts +145 -0
  27. package/dist/index-D79MSCee.d.mts.map +1 -0
  28. package/dist/index.cjs +4 -1
  29. package/dist/index.d.mts +2 -5
  30. package/dist/index.mjs +2 -1
  31. package/dist/runWorktree-BE795LxL.cjs +374 -0
  32. package/dist/runWorktree-BE795LxL.cjs.map +1 -0
  33. package/dist/runWorktree-SPzJvIBt.mjs +303 -0
  34. package/dist/runWorktree-SPzJvIBt.mjs.map +1 -0
  35. package/dist/worktreeOperations-BYmVU0UV.cjs +1350 -0
  36. package/dist/worktreeOperations-BYmVU0UV.cjs.map +1 -0
  37. package/dist/worktreeOperations-BrWG2muV.mjs +1194 -0
  38. package/dist/worktreeOperations-BrWG2muV.mjs.map +1 -0
  39. package/llms.txt +4 -0
  40. package/package.json +56 -41
  41. package/src/prompts/doompi-use-git/SKILL.md +26 -3
  42. package/dist/_virtual/_rolldown/runtime.cjs +0 -1
  43. package/dist/adapters/channel/worktreeChannel.cjs +0 -2
  44. package/dist/adapters/channel/worktreeChannel.cjs.map +0 -1
  45. package/dist/adapters/channel/worktreeChannel.d.cts +0 -40
  46. package/dist/adapters/channel/worktreeChannel.d.cts.map +0 -1
  47. package/dist/adapters/channel/worktreeChannel.d.mts +0 -40
  48. package/dist/adapters/channel/worktreeChannel.d.mts.map +0 -1
  49. package/dist/adapters/channel/worktreeChannel.mjs +0 -2
  50. package/dist/adapters/channel/worktreeChannel.mjs.map +0 -1
  51. package/dist/adapters/filesystem/atomicJson.cjs +0 -2
  52. package/dist/adapters/filesystem/atomicJson.cjs.map +0 -1
  53. package/dist/adapters/filesystem/atomicJson.mjs +0 -2
  54. package/dist/adapters/filesystem/atomicJson.mjs.map +0 -1
  55. package/dist/adapters/filesystem/paths.cjs +0 -2
  56. package/dist/adapters/filesystem/paths.cjs.map +0 -1
  57. package/dist/adapters/filesystem/paths.mjs +0 -2
  58. package/dist/adapters/filesystem/paths.mjs.map +0 -1
  59. package/dist/adapters/hub/hubClient.cjs +0 -2
  60. package/dist/adapters/hub/hubClient.cjs.map +0 -1
  61. package/dist/adapters/hub/hubClient.d.cts +0 -1
  62. package/dist/adapters/hub/hubClient.d.mts +0 -1
  63. package/dist/adapters/hub/hubClient.mjs +0 -2
  64. package/dist/adapters/hub/hubClient.mjs.map +0 -1
  65. package/dist/adapters/pi/extension.cjs +0 -2
  66. package/dist/adapters/pi/extension.cjs.map +0 -1
  67. package/dist/adapters/pi/extension.d.cts +0 -9
  68. package/dist/adapters/pi/extension.d.cts.map +0 -1
  69. package/dist/adapters/pi/extension.d.mts +0 -9
  70. package/dist/adapters/pi/extension.d.mts.map +0 -1
  71. package/dist/adapters/pi/extension.mjs +0 -2
  72. package/dist/adapters/pi/extension.mjs.map +0 -1
  73. package/dist/adapters/pi/extensions/runWorktreeTool.cjs +0 -15
  74. package/dist/adapters/pi/extensions/runWorktreeTool.cjs.map +0 -1
  75. package/dist/adapters/pi/extensions/runWorktreeTool.mjs +0 -15
  76. package/dist/adapters/pi/extensions/runWorktreeTool.mjs.map +0 -1
  77. package/dist/adapters/web/worktreesChannel.cjs +0 -2
  78. package/dist/adapters/web/worktreesChannel.cjs.map +0 -1
  79. package/dist/adapters/web/worktreesChannel.d.cts +0 -21
  80. package/dist/adapters/web/worktreesChannel.d.cts.map +0 -1
  81. package/dist/adapters/web/worktreesChannel.d.mts +0 -21
  82. package/dist/adapters/web/worktreesChannel.d.mts.map +0 -1
  83. package/dist/adapters/web/worktreesChannel.mjs +0 -2
  84. package/dist/adapters/web/worktreesChannel.mjs.map +0 -1
  85. package/dist/adapters/worktree/dependencyInstall.cjs +0 -2
  86. package/dist/adapters/worktree/dependencyInstall.cjs.map +0 -1
  87. package/dist/adapters/worktree/dependencyInstall.mjs +0 -2
  88. package/dist/adapters/worktree/dependencyInstall.mjs.map +0 -1
  89. package/dist/adapters/worktree/gitCli.cjs +0 -4
  90. package/dist/adapters/worktree/gitCli.cjs.map +0 -1
  91. package/dist/adapters/worktree/gitCli.mjs +0 -4
  92. package/dist/adapters/worktree/gitCli.mjs.map +0 -1
  93. package/dist/adapters/worktree/repositoryIdentity.cjs +0 -2
  94. package/dist/adapters/worktree/repositoryIdentity.cjs.map +0 -1
  95. package/dist/adapters/worktree/repositoryIdentity.mjs +0 -2
  96. package/dist/adapters/worktree/repositoryIdentity.mjs.map +0 -1
  97. package/dist/adapters/worktree/worktreeOperations.cjs +0 -2
  98. package/dist/adapters/worktree/worktreeOperations.cjs.map +0 -1
  99. package/dist/adapters/worktree/worktreeOperations.d.cts +0 -32
  100. package/dist/adapters/worktree/worktreeOperations.d.cts.map +0 -1
  101. package/dist/adapters/worktree/worktreeOperations.d.mts +0 -32
  102. package/dist/adapters/worktree/worktreeOperations.d.mts.map +0 -1
  103. package/dist/adapters/worktree/worktreeOperations.mjs +0 -2
  104. package/dist/adapters/worktree/worktreeOperations.mjs.map +0 -1
  105. package/dist/adapters/worktree/worktreeRegistry.cjs +0 -2
  106. package/dist/adapters/worktree/worktreeRegistry.cjs.map +0 -1
  107. package/dist/adapters/worktree/worktreeRegistry.mjs +0 -2
  108. package/dist/adapters/worktree/worktreeRegistry.mjs.map +0 -1
  109. package/dist/commands/doomGitCommand.cjs +0 -2
  110. package/dist/commands/doomGitCommand.cjs.map +0 -1
  111. package/dist/commands/doomGitCommand.mjs +0 -2
  112. package/dist/commands/doomGitCommand.mjs.map +0 -1
  113. package/dist/container/index.cjs +0 -2
  114. package/dist/container/index.cjs.map +0 -1
  115. package/dist/container/index.d.cts +0 -6
  116. package/dist/container/index.d.cts.map +0 -1
  117. package/dist/container/index.d.mts +0 -6
  118. package/dist/container/index.d.mts.map +0 -1
  119. package/dist/container/index.mjs +0 -2
  120. package/dist/container/index.mjs.map +0 -1
  121. package/dist/extensions/pi.d.cts +0 -2
  122. package/dist/hubApi.cjs +0 -2
  123. package/dist/hubApi.cjs.map +0 -1
  124. package/dist/hubApi.d.cts +0 -6
  125. package/dist/hubApi.d.cts.map +0 -1
  126. package/dist/hubApi.d.mts +0 -6
  127. package/dist/hubApi.d.mts.map +0 -1
  128. package/dist/hubApi.mjs +0 -2
  129. package/dist/hubApi.mjs.map +0 -1
  130. package/dist/index.d.cts +0 -5
  131. package/dist/schemas/runWorktreeTool.cjs +0 -2
  132. package/dist/schemas/runWorktreeTool.cjs.map +0 -1
  133. package/dist/schemas/runWorktreeTool.mjs +0 -2
  134. package/dist/schemas/runWorktreeTool.mjs.map +0 -1
  135. package/dist/services/extensionService.cjs +0 -2
  136. package/dist/services/extensionService.cjs.map +0 -1
  137. package/dist/services/extensionService.d.cts +0 -8
  138. package/dist/services/extensionService.d.cts.map +0 -1
  139. package/dist/services/extensionService.d.mts +0 -8
  140. package/dist/services/extensionService.d.mts.map +0 -1
  141. package/dist/services/extensionService.mjs +0 -2
  142. package/dist/services/extensionService.mjs.map +0 -1
  143. package/dist/services/support/errors.cjs +0 -2
  144. package/dist/services/support/errors.cjs.map +0 -1
  145. package/dist/services/support/errors.mjs +0 -2
  146. package/dist/services/support/errors.mjs.map +0 -1
  147. package/dist/services/worktreeNaming.cjs +0 -2
  148. package/dist/services/worktreeNaming.cjs.map +0 -1
  149. package/dist/services/worktreeNaming.d.cts +0 -27
  150. package/dist/services/worktreeNaming.d.cts.map +0 -1
  151. package/dist/services/worktreeNaming.d.mts +0 -27
  152. package/dist/services/worktreeNaming.d.mts.map +0 -1
  153. package/dist/services/worktreeNaming.mjs +0 -2
  154. package/dist/services/worktreeNaming.mjs.map +0 -1
  155. package/dist/types/extension.d.cts +0 -17
  156. package/dist/types/extension.d.cts.map +0 -1
  157. package/dist/types/extension.d.mts +0 -17
  158. package/dist/types/extension.d.mts.map +0 -1
  159. package/dist/types/webWorktrees.cjs +0 -2
  160. package/dist/types/webWorktrees.cjs.map +0 -1
  161. package/dist/types/webWorktrees.mjs +0 -2
  162. package/dist/types/webWorktrees.mjs.map +0 -1
  163. package/dist/types/worktreeRegistry.d.cts +0 -41
  164. package/dist/types/worktreeRegistry.d.cts.map +0 -1
  165. package/dist/types/worktreeRegistry.d.mts +0 -41
  166. package/dist/types/worktreeRegistry.d.mts.map +0 -1
  167. package/dist/webHub.cjs +0 -1
  168. package/dist/webHub.d.cts +0 -2
  169. package/dist/webHub.d.mts +0 -2
  170. package/dist/webHub.mjs +0 -1
  171. package/src/exports/webClient.ts +0 -1
  172. package/src/types/webWorktrees.ts +0 -55
  173. package/src/types/worktreeRegistry.ts +0 -69
  174. package/src/web/components/RunWorktreeToolMessage.tsx +0 -37
  175. package/src/web/components/WorktreesActivitySection.tsx +0 -64
  176. package/src/web/components/WorktreesPanel.tsx +0 -125
  177. package/src/web/components/toolRenderers.ts +0 -7
  178. package/src/web/index.ts +0 -30
  179. package/src/web/stores/worktreesActivityStore.ts +0 -124
  180. package/src/web/tsconfig.json +0 -22
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.mjs","names":["contribution","readLine","contribution","payloadOf","errorTargetFor","failureText","contribution","contribution","contribution","contribution","contribution","apiRoute","channelGitChanges","channelGitWorktrees","rootSession","hookAgentSettled","hookToolExecutionEnd","resourceDoompiGit","resourceDoompiGitReadme","resourceDoompiUseGit","toolRunWorktree"],"sources":["../../src/extensions/workspaces/sessions/(backend)/_lib/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/services/branchDiff/index.ts","../../src/services/gitAuth/index.ts","../../src/services/newSessionRequest/index.ts","../../src/extensions/(backend)/api/git/_lib/route.server.ts","../../src/extensions/(backend)/api/git/route.server.ts","../../src/services/gitFailure/index.ts","../../src/services/gitSync/index.ts","../../src/types/gitReview.ts","../../src/extensions/(backend)/channel/_lib/git-changes.server.ts","../../src/extensions/(backend)/channel/git-changes.server.ts","../../src/types/webWorktrees.ts","../../src/extensions/(backend)/channel/_lib/git-worktrees.server.ts","../../src/extensions/(backend)/channel/git-worktrees.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-execution-end.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGitReadme.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiGitReadme.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiUseGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiUseGit.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.server.ts","../../generated/server.ts"],"sourcesContent":["import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport {\n type DoomHeadlessExecutionContext,\n type DoomHeadlessHook,\n type DoomHeadlessResource,\n type DoomHeadlessTool,\n type DoomHeadlessToolResult,\n} from '@agimon-ai/doompi-core/headless';\nimport { readPackageResource, type DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\nimport { readDoomSessionDelivery } from '@agimon-ai/doompi-session';\n\nimport { RunWorktreeToolSchema, type RunWorktreeToolParams } from '../../../../../schemas/runWorktreeTool';\nimport { createWorktreeGit } from '../../../../../services/gitCli';\nimport {\n executeRunWorktreeTool,\n RUN_WORKTREE_DESCRIPTION,\n RUN_WORKTREE_TOOL_NAME,\n validateParams,\n} from '../../../../../services/runWorktree';\nimport {\n createWorktreeMessageInbox,\n GIT_SESSION_CHANGED_EVENT,\n WORKTREE_MESSAGE_VERSION,\n} from '../../../../../services/worktreeEvents';\nimport { createWorktreeOperations } from '../../../../../services/worktreeOperations';\n\nfunction progressResult(action: RunWorktreeToolParams['action'], label: string): DoomHeadlessToolResult {\n return { content: [{ type: 'text', text: label }], details: { action } };\n}\n\nexport function createGitSession({ context, host: serverHost }: DoomServerPluginContext) {\n if (serverHost.context.directEvents === undefined)\n throw new Error('Git headless facet requires the session direct event bus.');\n if (serverHost.context.sessionId === undefined) throw new Error('Git headless facet requires a session identity.');\n const sessionId = serverHost.context.sessionId;\n const directEvents = serverHost.context.directEvents;\n const messageInbox = createWorktreeMessageInbox(directEvents, sessionId);\n const operations = createWorktreeOperations({\n git: createWorktreeGit(),\n sessionService: serverHost.context.sessionService,\n messageInbox,\n sessionDelivery: () => readDoomSessionDelivery(context),\n });\n const resources: DoomHeadlessResource[] = [\n {\n // The package index is Help-catalog material, not standing instruction, so it\n // only enters the prompt while Help mode is active. Matches the Pi facet,\n // which has always routed this through the Help service.\n when: { state: { 'minor-mode': 'help' }, attribution: { kind: 'minor', mode: 'help' } },\n name: 'doompi-git',\n kind: 'context',\n read: () => readPackageResource(import.meta.url, 'llms.txt'),\n },\n {\n name: 'doompi-use-git',\n kind: 'skill',\n read: () => readPackageResource(import.meta.url, 'src/prompts/doompi-use-git/SKILL.md'),\n },\n ];\n\n const tool: DoomHeadlessTool<typeof RunWorktreeToolSchema> = {\n name: RUN_WORKTREE_TOOL_NAME,\n label: 'Worktree',\n description: RUN_WORKTREE_DESCRIPTION,\n parameters: RunWorktreeToolSchema,\n promptSnippet: 'Create and manage Git worktree sessions',\n executionMode: 'serial',\n async execute(_toolCallId, parameters, signal, onUpdate, execution) {\n const params = validateParams(parameters) as RunWorktreeToolParams;\n return executeRunWorktreeTool(params, operations, execution, {\n ...(signal === undefined ? {} : { signal }),\n onProgress: (label) => onUpdate?.(progressResult(params.action, label)),\n });\n },\n };\n // A tool call or a settled turn may have changed the checkout. The hub's\n // '# diff' channel coalesces these, so a burst of tool calls costs one recount.\n const changed = (_event: unknown, execution: DoomHeadlessExecutionContext): void => {\n directEvents.publish(GIT_SESSION_CHANGED_EVENT, execution.sessionId, { version: WORKTREE_MESSAGE_VERSION });\n };\n const hooks: DoomHeadlessHook[] = [\n { event: 'tool_execution_end', handle: changed },\n { event: 'agent_settled', handle: changed },\n ];\n return { value: { resources, tool, hooks }, onDispose: () => messageInbox.close() };\n}\n\nconst root = defineRoot(createGitSession);\nexport type GitServerScope = Awaited<ReturnType<typeof root>>['value'];\nexport default root;\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/root.server';\n\nexport default defineRoot(contribution);\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type {\n GitChangesView,\n GitDiffHunk,\n GitDiffRow,\n GitReviewFileDiff,\n GitReviewFileEntry,\n GitReviewFileStatus,\n} from '../../types/gitReview';\nimport { READ_TIMEOUT_MS, runGit } from '../gitCli';\nimport type { BranchDiff, BranchDiffOptions, BranchReview, ReviewBase } from './type';\n\n/**\n * What a session's checkout changed against its base, the way a pull request\n * shows it: every commit since the branch left its base, plus staged, unstaged\n * and untracked work.\n *\n * DESIGN PATTERNS:\n * - git computes every diff. The counts come from `--numstat` and the hunks\n * from the same unified diff, so the two always agree.\n * - The base is the worktree's own recorded base when there is one, then the\n * remote's default branch, then the branch's upstream, and with none of those\n * only uncommitted work counts. It is always named in the UI.\n * - Untracked files are read only when they are small regular files; a symlink\n * shows its link text and is never followed.\n *\n * AVOID:\n * - Passing a browser path to git without checking it against the change set.\n */\n\n/** git's well-known empty tree, the base of a repository with no commits. */\nconst EMPTY_TREE = '4b825dc642cb6eb9a060e54bf8d69288fbee4904';\nconst MAX_LISTED_FILES = 500;\nconst MAX_UNTRACKED_COUNTED = 200;\nconst MAX_FILE_BYTES = 1_048_576;\nconst MAX_ROWS = 5_000;\nconst BINARY_PROBE_BYTES = 8_192;\nconst SHORT_SHA = 7;\nconst DEFAULT_BRANCHES = ['main', 'master'];\n\nasync function read(cwd: string, args: readonly string[]): Promise<string | undefined> {\n const result = await runGit(cwd, args, { timeout: READ_TIMEOUT_MS });\n return result.code === 0 ? result.stdout : undefined;\n}\n\nasync function readLine(cwd: string, args: readonly string[]): Promise<string | undefined> {\n const out = (await read(cwd, args))?.trim();\n return out === undefined || out === '' ? undefined : out;\n}\n\nasync function commitExists(cwd: string, ref: string): Promise<boolean> {\n return (await readLine(cwd, ['rev-parse', '--verify', '--quiet', `${ref}^{commit}`])) !== undefined;\n}\n\n/** A local branch's upstream, so the review measures against what fetch keeps current. */\nasync function upstreamOf(cwd: string, ref: string): Promise<string | undefined> {\n return readLine(cwd, ['rev-parse', '--abbrev-ref', '--symbolic-full-name', `${ref}@{upstream}`]);\n}\n\n/** The ref the review is measured against. Exported for sync, whose rebase uses the same base. */\nexport async function resolveBaseRef(\n cwd: string,\n branch: string | undefined,\n recordedBaseRef?: string,\n): Promise<string | undefined> {\n // An existing-branch worktree records the branch itself as its base, which\n // would make every review empty.\n const recordedIsSelf =\n recordedBaseRef === undefined ||\n (branch !== undefined && (recordedBaseRef === branch || recordedBaseRef.endsWith(`/${branch}`)));\n if (!recordedIsSelf && recordedBaseRef !== undefined && (await commitExists(cwd, recordedBaseRef))) {\n const isLocal =\n (await readLine(cwd, ['rev-parse', '--verify', '--quiet', `refs/heads/${recordedBaseRef}`])) !== undefined;\n return (isLocal ? await upstreamOf(cwd, recordedBaseRef) : undefined) ?? recordedBaseRef;\n }\n const originHead = await readLine(cwd, ['symbolic-ref', '--quiet', '--short', 'refs/remotes/origin/HEAD']);\n if (originHead !== undefined) return originHead;\n for (const name of DEFAULT_BRANCHES) {\n if (await commitExists(cwd, `origin/${name}`)) return `origin/${name}`;\n }\n return branch === undefined ? undefined : upstreamOf(cwd, branch);\n}\n\nasync function resolveBase(cwd: string, branch: string | undefined, recordedBaseRef?: string): Promise<ReviewBase> {\n const ref = await resolveBaseRef(cwd, branch, recordedBaseRef);\n const head = await commitExists(cwd, 'HEAD');\n if (ref !== undefined && head) {\n const mergeBase = await readLine(cwd, ['merge-base', ref, 'HEAD']);\n if (mergeBase !== undefined) return { ref, from: mergeBase, mergeBase: mergeBase.slice(0, SHORT_SHA) };\n }\n return { from: head ? 'HEAD' : EMPTY_TREE };\n}\n\n/** NUL-separated fields from a `-z` listing, without the trailing empty one. */\nfunction zFields(out: string | undefined): string[] {\n if (out === undefined || out === '') return [];\n const fields = out.split('\\0');\n if (fields.at(-1) === '') fields.pop();\n return fields;\n}\n\nconst NAME_STATUS: Readonly<Record<string, GitReviewFileStatus>> = {\n A: 'added',\n D: 'deleted',\n M: 'modified',\n T: 'modified',\n};\n\n/** Line count of a small regular file, or undefined when it is binary, large, or not a regular file. */\nfunction untrackedLines(root: string, relPath: string): { lines: number; binary: boolean } | undefined {\n const absolute = path.join(root, relPath);\n let stat: fs.Stats;\n try {\n stat = fs.lstatSync(absolute);\n } catch {\n return undefined;\n }\n if (stat.isSymbolicLink()) return { lines: 1, binary: false };\n if (!stat.isFile() || stat.size > MAX_FILE_BYTES) return undefined;\n const content = fs.readFileSync(absolute);\n if (content.subarray(0, BINARY_PROBE_BYTES).includes(0)) return { lines: 0, binary: true };\n if (content.length === 0) return { lines: 0, binary: false };\n const text = content.toString('utf8');\n const newlines = text.split('\\n').length - 1;\n return { lines: text.endsWith('\\n') ? newlines : newlines + 1, binary: false };\n}\n\n/** The hunks of a unified diff, numbering each row by the file it lives in. */\nexport function parseUnifiedDiff(diff: string): { hunks: GitDiffHunk[]; binary: boolean; rows: number } {\n const hunks: GitDiffHunk[] = [];\n let current: GitDiffHunk | undefined;\n let oldLine = 0;\n let newLine = 0;\n let rows = 0;\n let binary = false;\n for (const line of diff.split('\\n')) {\n const header = /^@@ -(\\d+)(?:,\\d+)? \\+(\\d+)(?:,\\d+)? @@/u.exec(line);\n if (header !== null) {\n oldLine = Number(header[1]);\n newLine = Number(header[2]);\n current = { start: newLine, rows: [] };\n hunks.push(current);\n continue;\n }\n if (current === undefined) {\n if (line.startsWith('Binary files ') || line === 'GIT binary patch') binary = true;\n continue;\n }\n const marker = line[0];\n let row: GitDiffRow | undefined;\n if (marker === ' ') row = { marker: ' ', line: newLine, content: line.slice(1) };\n else if (marker === '-') row = { marker: '-', line: oldLine, content: line.slice(1) };\n else if (marker === '+') row = { marker: '+', line: newLine, content: line.slice(1) };\n // `\` and the trailing empty split are not rows.\n if (row === undefined) continue;\n if (marker !== '+') oldLine += 1;\n if (marker !== '-') newLine += 1;\n current.rows.push(row);\n rows += 1;\n }\n return { hunks, binary, rows };\n}\n\nexport function createBranchDiff(): BranchDiff {\n return {\n async review(cwd: string, options: BranchDiffOptions = {}): Promise<BranchReview | undefined> {\n const root = await readLine(cwd, ['rev-parse', '--show-toplevel']);\n if (root === undefined) return undefined;\n const branch = await readLine(root, ['symbolic-ref', '--quiet', '--short', 'HEAD']);\n const base = await resolveBase(root, branch, options.recordedBaseRef);\n\n const numstat = zFields(await read(root, ['diff', '--numstat', '-z', '--no-renames', base.from]));\n const nameStatus = zFields(await read(root, ['diff', '--name-status', '-z', '--no-renames', base.from]));\n const unmerged = new Set(zFields(await read(root, ['diff', '--name-only', '--diff-filter=U', '-z'])));\n const statusOf = new Map<string, GitReviewFileStatus>();\n for (let index = 0; index + 1 < nameStatus.length; index += 2) {\n statusOf.set(nameStatus[index + 1] ?? '', NAME_STATUS[(nameStatus[index] ?? '').charAt(0)] ?? 'modified');\n }\n\n const entries: GitReviewFileEntry[] = [];\n for (const field of numstat) {\n const [added = '', removed = '', ...rest] = field.split('\\t');\n const filePath = rest.join('\\t');\n if (filePath === '') continue;\n const binary = added === '-' && removed === '-';\n entries.push({\n path: filePath,\n status: unmerged.has(filePath) ? 'conflicted' : (statusOf.get(filePath) ?? 'modified'),\n added: binary ? 0 : Number(added),\n removed: binary ? 0 : Number(removed),\n ...(binary ? { binary: true } : {}),\n });\n }\n\n const untracked = zFields(await read(root, ['ls-files', '--others', '--exclude-standard', '-z']));\n untracked.forEach((relPath, index) => {\n const counted = index < MAX_UNTRACKED_COUNTED ? untrackedLines(root, relPath) : undefined;\n entries.push({\n path: relPath,\n status: 'untracked',\n added: counted?.lines ?? 0,\n removed: 0,\n ...(counted?.binary ? { binary: true } : {}),\n });\n });\n entries.sort((left, right) => left.path.localeCompare(right.path));\n\n const conflicts = [...unmerged];\n const rebaseMerge = await readLine(root, ['rev-parse', '--git-path', 'rebase-merge']);\n const rebaseApply = await readLine(root, ['rev-parse', '--git-path', 'rebase-apply']);\n const rebasing = [rebaseMerge, rebaseApply].some(\n (gitPath) => gitPath !== undefined && fs.existsSync(path.resolve(root, gitPath)),\n );\n\n const upstreamRef = branch === undefined ? undefined : await upstreamOf(root, branch);\n let upstream: GitChangesView['upstream'];\n if (upstreamRef !== undefined) {\n const counts = await readLine(root, ['rev-list', '--left-right', '--count', `${upstreamRef}...HEAD`]);\n const [behind, ahead] = (counts ?? '').split(/\\s+/u).map(Number);\n if (Number.isInteger(ahead) && Number.isInteger(behind))\n upstream = { ref: upstreamRef, ahead: ahead!, behind: behind! };\n }\n\n const truncated = entries.length > MAX_LISTED_FILES || untracked.length > MAX_UNTRACKED_COUNTED;\n const added = entries.reduce((sum, entry) => sum + entry.added, 0);\n const removed = entries.reduce((sum, entry) => sum + entry.removed, 0);\n const changes: GitChangesView = {\n added,\n removed,\n files: entries.length,\n ...(branch === undefined ? {} : { branch }),\n ...(base.ref === undefined ? {} : { base: base.ref }),\n ...(truncated ? { truncated: true } : {}),\n ...(upstream === undefined ? {} : { upstream }),\n ...(rebasing ? { rebase: { conflicts } } : {}),\n };\n return {\n root,\n base,\n changes,\n summary: {\n repository: true,\n files: entries.slice(0, MAX_LISTED_FILES),\n ...(branch === undefined ? {} : { branch }),\n ...(base.ref === undefined ? {} : { base: base.ref }),\n ...(base.mergeBase === undefined ? {} : { mergeBase: base.mergeBase }),\n ...(truncated ? { truncated: true } : {}),\n },\n };\n },\n\n async fileDiff(review: BranchReview, filePath: string): Promise<GitReviewFileDiff> {\n const entry = review.summary.files.find((file) => file.path === filePath);\n if (entry === undefined) throw new Error('That path is not in this review.');\n if (entry.status === 'untracked') {\n const absolute = path.join(review.root, entry.path);\n const stat = fs.lstatSync(absolute);\n if (stat.isSymbolicLink()) {\n return {\n path: entry.path,\n hunks: [{ start: 1, rows: [{ marker: '+', line: 1, content: fs.readlinkSync(absolute) }] }],\n };\n }\n if (!stat.isFile() || stat.size > MAX_FILE_BYTES) return { path: entry.path, hunks: [], tooLarge: true };\n const content = fs.readFileSync(absolute);\n if (content.subarray(0, BINARY_PROBE_BYTES).includes(0)) return { path: entry.path, hunks: [], binary: true };\n const lines = content.toString('utf8').split('\\n');\n if (lines.at(-1) === '') lines.pop();\n if (lines.length > MAX_ROWS) return { path: entry.path, hunks: [], tooLarge: true };\n return {\n path: entry.path,\n hunks:\n lines.length === 0\n ? []\n : [{ start: 1, rows: lines.map((content, index) => ({ marker: '+', line: index + 1, content })) }],\n };\n }\n const result = await runGit(\n review.root,\n [\n 'diff',\n '-U3',\n '--no-color',\n '--no-ext-diff',\n '--no-textconv',\n '--no-renames',\n review.base.from,\n '--',\n `:(top,literal)${entry.path}`,\n ],\n { timeout: READ_TIMEOUT_MS, maxBuffer: MAX_FILE_BYTES },\n );\n if (result.overflow) return { path: entry.path, hunks: [], tooLarge: true };\n if (result.code !== 0) throw new Error(`git diff failed (exit ${String(result.code)}).`);\n const parsed = parseUnifiedDiff(result.stdout);\n if (parsed.binary || entry.binary === true) return { path: entry.path, hunks: [], binary: true };\n if (parsed.rows > MAX_ROWS) return { path: entry.path, hunks: [], tooLarge: true };\n return { path: entry.path, hunks: parsed.hunks };\n },\n };\n}\n","import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport type { GitAuthView } from '../../types/gitAuth';\nimport { readJson, writeJsonAtomic } from '../atomicJson';\nimport { invalidRequest } from '../errors';\nimport { credentialsFile, doomGitRoot } from '../paths';\nimport type { GitAuthConfig, GitAuthFile, GitAuthStore, RemoteEnv } from './type';\n\n/**\n * Per-workspace remote auth for doompi-git's own fetch, pull, push and rebase.\n *\n * DESIGN PATTERNS:\n * - One file outside every repository, folder 0700 and file 0600, repaired on\n * read if something loosened it. The token never leaves this module except\n * into the environment of one git child process.\n * - Config reaches git through GIT_CONFIG_COUNT environment entries, never\n * argv, so nothing secret shows in `ps`. The first entry empties the\n * credential helper list, which is what keeps macOS's osxkeychain helper from\n * storing the token after a successful push.\n * - The token is offered only to the host it was entered for. A repository\n * whose remote points anywhere else gets this machine's own credentials.\n *\n * AVOID:\n * - Touching process.env. The hub runs every session; anything set there\n * would reach the agent's shell, which the user ruled out.\n */\n\nconst OWNER_ONLY_DIRECTORY = 0o700;\nconst OWNER_ONLY_FILE = 0o600;\nconst LOOSE_BITS = 0o077;\nconst HOST_PATTERN = /^[a-z0-9.-]{1,253}(:\\d{1,5})?$/u;\nconst MAX_USERNAME = 256;\nconst MAX_TOKEN = 4096;\nconst SETTINGS_HINT = 'Open settings, then repository, then git remote.';\n\n/** Environment that would make git log or skip what this module relies on. */\nconst STRIPPED_ALWAYS = ['GIT_CURL_VERBOSE', 'GIT_TRACE_REDACT'];\nconst STRIPPED_PREFIXES = ['GIT_TRACE'];\n/** Environment that could redirect or override credentials when the workspace's own are in play. */\nconst STRIPPED_CREDENTIALED = [\n 'GIT_CONFIG_PARAMETERS',\n 'GIT_CONFIG_COUNT',\n 'GIT_SSL_NO_VERIFY',\n 'SSH_ASKPASS',\n 'GIT_SSH',\n 'GIT_SSH_COMMAND',\n];\nconst CONFIG_ENTRY = /^GIT_CONFIG_(KEY|VALUE)_\\d+$/u;\n\n/** The inline helper: answers `get` from this child's environment, and ignores `store` and `erase`. */\nconst ENV_CREDENTIAL_HELPER =\n '!f(){ test \"$1\" = get && printf \"username=%s\\\\npassword=%s\\\\n\" \"$DOOMPI_GIT_USERNAME\" \"$DOOMPI_GIT_TOKEN\"; }; f';\n\n/** Whether a value holds an ASCII control character; a newline in a credential field could add a line to git's credential protocol. */\nfunction hasControl(value: string): boolean {\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code < 0x20 || code === 0x7f) return true;\n }\n return false;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** The workspace key: the canonical root, so a symlinked path and its target share one entry. */\nfunction workspaceKey(workspaceRoot: string): string {\n try {\n return fs.realpathSync(workspaceRoot);\n } catch {\n return path.resolve(workspaceRoot);\n }\n}\n\nfunction expandHome(keyPath: string, homeDir: string): string {\n return keyPath.startsWith('~/') ? path.join(homeDir, keyPath.slice(2)) : keyPath;\n}\n\nfunction parseConfig(value: unknown): GitAuthConfig | undefined {\n if (!isRecord(value)) return undefined;\n if (value.method === 'none') return { method: 'none' };\n if (value.method === 'ssh') {\n if (value.keyPath === undefined) return { method: 'ssh' };\n return typeof value.keyPath === 'string' && value.keyPath !== ''\n ? { method: 'ssh', keyPath: value.keyPath }\n : undefined;\n }\n if (\n value.method === 'https' &&\n typeof value.host === 'string' &&\n typeof value.username === 'string' &&\n typeof value.token === 'string' &&\n value.token !== ''\n ) {\n return { method: 'https', host: value.host, username: value.username, token: value.token };\n }\n return undefined;\n}\n\n/** What the browser may see. The token becomes a yes or no. */\nexport function publicView(config: GitAuthConfig): GitAuthView {\n if (config.method === 'ssh')\n return config.keyPath === undefined\n ? { method: 'ssh', ssh: {} }\n : { method: 'ssh', ssh: { keyPath: config.keyPath } };\n if (config.method === 'https') {\n return { method: 'https', https: { host: config.host, username: config.username, hasToken: config.token !== '' } };\n }\n return { method: 'none' };\n}\n\n/**\n * A browser save request, checked field by field. An absent HTTPS token keeps\n * the saved one, and only for the same host: a token never follows a host it\n * was not entered for.\n */\nexport function parseGitAuthSave(request: unknown, current: GitAuthConfig, homeDir: string): GitAuthConfig {\n if (!isRecord(request))\n throw invalidRequest('The git auth request is not an object.', 'Send method none, ssh or https.');\n if (request.method === 'none') return { method: 'none' };\n if (request.method === 'ssh') {\n if (request.keyPath === undefined || request.keyPath === '') return { method: 'ssh' };\n if (typeof request.keyPath !== 'string' || hasControl(request.keyPath)) {\n throw invalidRequest('The key path is not a plain path.', 'Give the key as an absolute path or one under ~/.');\n }\n const keyPath = request.keyPath.trim();\n if (!keyPath.startsWith('/') && !keyPath.startsWith('~/')) {\n throw invalidRequest('The key path is not absolute.', 'Give the key as an absolute path or one under ~/.');\n }\n let isFile = false;\n try {\n isFile = fs.statSync(expandHome(keyPath, homeDir)).isFile();\n } catch {\n isFile = false;\n }\n if (!isFile)\n throw invalidRequest(`No key file at ${keyPath}.`, 'Check the path, or leave it blank to use ssh-agent.');\n return { method: 'ssh', keyPath };\n }\n if (request.method === 'https') {\n const host = typeof request.host === 'string' ? request.host.trim().toLowerCase() : '';\n if (!HOST_PATTERN.test(host))\n throw invalidRequest('The host is not a host name.', 'Use a host like github.com, with an optional :port.');\n const username = typeof request.username === 'string' ? request.username.trim() : '';\n if (username === '' || username.length > MAX_USERNAME || hasControl(username)) {\n throw invalidRequest('The username is empty or not plain text.', 'Enter the username the host knows you by.');\n }\n if (request.token !== undefined && request.token !== '') {\n if (typeof request.token !== 'string' || request.token.length > MAX_TOKEN || hasControl(request.token)) {\n throw invalidRequest('The token is not plain text.', 'Paste the token again without line breaks.');\n }\n return { method: 'https', host, username, token: request.token };\n }\n if (current.method === 'https' && current.host === host && current.token !== '') {\n return { method: 'https', host, username, token: current.token };\n }\n throw invalidRequest(\n current.method === 'https' ? 'The host changed, so the saved token cannot follow it.' : 'A token is required.',\n 'Enter the personal access token for this host.',\n );\n }\n throw invalidRequest('The git auth method is unknown.', 'Send method none, ssh or https.');\n}\n\n/** Tightens a file or folder something left readable by group or others. */\nfunction tighten(target: string, mode: number): void {\n try {\n if ((fs.statSync(target).mode & LOOSE_BITS) !== 0) fs.chmodSync(target, mode);\n } catch {\n // Absent is fine: the first save creates it with the right mode.\n }\n}\n\nexport function createGitAuthStore(homeDir: string = os.homedir()): GitAuthStore {\n const file = credentialsFile(homeDir);\n const readFile = (): GitAuthFile => {\n tighten(file, OWNER_ONLY_FILE);\n const raw = readJson<unknown>(file);\n const workspaces: Record<string, GitAuthConfig> = {};\n if (isRecord(raw) && raw.version === 1 && isRecord(raw.workspaces)) {\n for (const [key, value] of Object.entries(raw.workspaces)) {\n // A malformed entry is treated as unset rather than guessed at.\n const config = parseConfig(value);\n if (config !== undefined) workspaces[key] = config;\n }\n }\n return { version: 1, workspaces };\n };\n const read = (workspaceRoot: string): GitAuthConfig =>\n readFile().workspaces[workspaceKey(workspaceRoot)] ?? { method: 'none' };\n\n return {\n read,\n view: (workspaceRoot) => publicView(read(workspaceRoot)),\n save(workspaceRoot, request) {\n const key = workspaceKey(workspaceRoot);\n const current = readFile();\n const next = parseGitAuthSave(request, current.workspaces[key] ?? { method: 'none' }, homeDir);\n const root = doomGitRoot(homeDir);\n fs.mkdirSync(root, { recursive: true, mode: OWNER_ONLY_DIRECTORY });\n fs.chmodSync(root, OWNER_ONLY_DIRECTORY);\n const workspaces = { ...current.workspaces };\n if (next.method === 'none') delete workspaces[key];\n else workspaces[key] = next;\n writeJsonAtomic(file, { version: 1, workspaces } satisfies GitAuthFile);\n fs.chmodSync(file, OWNER_ONLY_FILE);\n return publicView(next);\n },\n };\n}\n\n/** The transport and host a remote URL names, or undefined for a local path or anything else. */\nexport function remoteTransport(url: string): { kind: 'https' | 'http' | 'ssh'; host: string } | undefined {\n const trimmed = url.trim();\n if (/^[a-z][a-z0-9+.-]*:\\/\\//iu.test(trimmed)) {\n try {\n const parsed = new URL(trimmed);\n const kind =\n parsed.protocol === 'https:'\n ? 'https'\n : parsed.protocol === 'http:'\n ? 'http'\n : parsed.protocol === 'ssh:'\n ? 'ssh'\n : undefined;\n return kind === undefined ? undefined : { kind, host: parsed.host.toLowerCase() };\n } catch {\n return undefined;\n }\n }\n // scp-like `user@host:path`: a colon before any slash, and not a Windows drive.\n const scp = /^(?:[^@/]+@)?([^:/]+):(?!\\/\\/)/u.exec(trimmed);\n if (scp !== null && scp[1] !== undefined && scp[1].length > 1) return { kind: 'ssh', host: scp[1].toLowerCase() };\n return undefined;\n}\n\n/** Quotes one word for the POSIX shell git runs GIT_SSH_COMMAND through. */\nfunction shellQuote(value: string): string {\n return `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\n}\n\n/**\n * The environment for one fetch or push against `remoteUrl`.\n *\n * Every call drops tracing (which can log credentials) and turns prompts off,\n * because no terminal is attached. Only when the workspace's method matches the\n * remote does anything secret go in, and then only into this child's env.\n */\nexport function remoteEnv(\n config: GitAuthConfig,\n remoteUrl: string,\n baseEnv: NodeJS.ProcessEnv,\n homeDir: string,\n): RemoteEnv {\n const env: NodeJS.ProcessEnv = { ...baseEnv };\n for (const key of Object.keys(env)) {\n if (STRIPPED_ALWAYS.includes(key) || STRIPPED_PREFIXES.some((prefix) => key.startsWith(prefix))) delete env[key];\n }\n env.GIT_TERMINAL_PROMPT = '0';\n env.GCM_INTERACTIVE = 'never';\n\n const transport = remoteTransport(remoteUrl);\n const credentialed = (): void => {\n for (const key of Object.keys(env)) {\n if (STRIPPED_CREDENTIALED.includes(key) || CONFIG_ENTRY.test(key)) delete env[key];\n }\n // Takes precedence over a core.askPass the repository's own config names.\n env.GIT_ASKPASS = 'true';\n };\n\n if (config.method === 'https') {\n if (transport?.kind !== 'https' || transport.host !== config.host) {\n return {\n env,\n credentialed: false,\n mismatch: `This workspace's token is for https://${config.host}, and this remote is not.`,\n };\n }\n credentialed();\n env.GIT_CONFIG_COUNT = '3';\n env.GIT_CONFIG_KEY_0 = 'credential.helper';\n env.GIT_CONFIG_VALUE_0 = '';\n env.GIT_CONFIG_KEY_1 = `credential.https://${config.host}.helper`;\n env.GIT_CONFIG_VALUE_1 = ENV_CREDENTIAL_HELPER;\n env.GIT_CONFIG_KEY_2 = 'http.sslVerify';\n env.GIT_CONFIG_VALUE_2 = 'true';\n env.GIT_ALLOW_PROTOCOL = 'https';\n env.DOOMPI_GIT_USERNAME = config.username;\n env.DOOMPI_GIT_TOKEN = config.token;\n return { env, credentialed: true };\n }\n\n if (config.method === 'ssh') {\n if (transport?.kind !== 'ssh') {\n return { env, credentialed: false, mismatch: 'This workspace uses SSH, and this remote is not an SSH remote.' };\n }\n credentialed();\n const identity =\n config.keyPath === undefined\n ? []\n : ['-i', shellQuote(expandHome(config.keyPath, homeDir)), '-o', 'IdentitiesOnly=yes'];\n // No StrictHostKeyChecking override: an unknown host is refused, and the\n // recovery says to trust it once from a terminal.\n env.GIT_SSH_COMMAND = ['ssh', ...identity, '-o', 'BatchMode=yes', '-o', 'ConnectTimeout=15'].join(' ');\n env.GIT_ALLOW_PROTOCOL = 'ssh';\n return { env, credentialed: true };\n }\n\n return { env, credentialed: false };\n}\n\nexport { SETTINGS_HINT };\n","// @scaffold-generated\nimport { validRefName } from '../worktreeNaming';\nimport type { NewSessionRequestResult } from './type';\n\nconst MAX_NAME_LENGTH = 120;\n\n/** Trimmed text, undefined when absent or blank, false when not text at all. */\nfunction optionalText(value: unknown): string | undefined | false {\n if (value === undefined) return undefined;\n if (typeof value !== 'string') return false;\n const trimmed = value.trim();\n return trimmed === '' ? undefined : trimmed;\n}\n\n/**\n * Validates a new-session dialog request for a worktree session. Every ref is\n * checked here, before it can reach git as a positional argument.\n */\nexport function newSessionRequest(body: unknown): NewSessionRequestResult {\n if (typeof body !== 'object' || body === null || Array.isArray(body)) return { error: 'A request body is required.' };\n const record = body as Record<string, unknown>;\n const branch = optionalText(record.branch);\n if (branch === undefined || branch === false || !validRefName(branch))\n return { error: 'A valid branch name is required.' };\n const name = optionalText(record.name);\n if (name === false || (name !== undefined && name.length > MAX_NAME_LENGTH))\n return { error: `The session name must be text of up to ${String(MAX_NAME_LENGTH)} characters.` };\n const named = name === undefined ? {} : { name };\n if (record.mode === 'existing-branch') {\n const remote = optionalText(record.remote);\n if (remote === false || (remote !== undefined && !validRefName(remote)))\n return { error: 'That remote name is not valid.' };\n return { mode: 'existing-branch', branch, ...(remote === undefined ? {} : { remote }), ...named };\n }\n if (record.mode === 'new-branch') {\n const baseRef = optionalText(record.baseRef);\n if (baseRef === false || (baseRef !== undefined && !validRefName(baseRef)))\n return { error: 'That base branch is not valid.' };\n return { mode: 'new-branch', branch, ...(baseRef === undefined ? {} : { baseRef }), ...named };\n }\n return { error: 'The mode must be existing-branch or new-branch.' };\n}\n","import os from 'node:os';\n\nimport type { DoomApi, DoomApiContext, DoomApiHandler } from '@agimon-ai/doompi-core/packageApi';\n\nimport {\n GIT_API_BASE_PATH,\n GIT_AUTH_PATH,\n GIT_BRANCHES_PATH,\n GIT_REVIEW_FILE_PATH,\n GIT_REVIEW_PATH,\n GIT_SESSIONS_PATH,\n} from '../../../../../constants/git';\nimport { createBranchDiff } from '../../../../../services/branchDiff';\nimport { DoomGitExpectedError } from '../../../../../services/errors';\nimport { createGitAuthStore } from '../../../../../services/gitAuth';\nimport { createWorktreeGit } from '../../../../../services/gitCli';\nimport { newSessionRequest } from '../../../../../services/newSessionRequest';\nimport { registryFile } from '../../../../../services/paths';\nimport { GIT_WORKTREE_LIFECYCLE_EVENT } from '../../../../../services/worktreeEvents';\nimport { createWorktreeOperations } from '../../../../../services/worktreeOperations';\nimport { createWorktreeRegistry } from '../../../../../services/worktreeRegistry';\nimport type { GitReviewSummary } from '../../../../../types/gitReview';\nimport type { GitBranchesResponse, GitSessionCreated } from '../../../../../types/gitSessions';\n\n/**\n * The worktree surface the cockpit panel calls.\n *\n * Hub-scoped because worktrees are a property of a repository, not of one\n * session: the panel lists and creates them whether or not the session that\n * made them is focused, and a session-scoped API would disappear with it.\n *\n * The panel names a repository by the hub's opaque id and never by path.\n * `resolveRepository` turns that into an admitted root, so a browser cannot\n * point this at a directory the cockpit was never given.\n */\nfunction badRequest(message: string): Response {\n return Response.json({ error: message }, { status: 400 });\n}\n\nfunction failed(error: unknown): Response {\n if (error instanceof DoomGitExpectedError) {\n return Response.json({ error: error.message, code: error.code }, { status: error.retryable ? 503 : 409 });\n }\n // Never the raw message: a git failure can carry a remote URL with a token.\n return Response.json({ error: 'The worktree operation failed.' }, { status: 500 });\n}\n\nexport const api: DoomApi = {\n basePath: GIT_API_BASE_PATH,\n start(context: DoomApiContext): DoomApiHandler {\n if (context.directEvents === undefined) throw new Error('Git hub API requires the direct event bus.');\n const directEvents = context.directEvents;\n const publishLifecycle = (sessionId: string, repositoryRoot: string): void => {\n directEvents.publish(GIT_WORKTREE_LIFECYCLE_EVENT, sessionId, { version: 1 as const, repositoryRoot });\n };\n const git = createWorktreeGit();\n const operations = createWorktreeOperations({\n git,\n sessionService: context.sessionService,\n ...(context.homeDirectory === undefined ? {} : { homeDir: context.homeDirectory }),\n });\n\n /**\n * The new-session dialog's routes: the workspace's branches, and a top-level\n * worktree session on one. Workspace-mounted only, and always rooted at the\n * mount's own workspace, so a request can never name another directory.\n */\n const newSession = async (request: Request, url: URL): Promise<Response | undefined> => {\n const isBranches = request.method === 'GET' && url.pathname === GIT_BRANCHES_PATH;\n const isCreate = request.method === 'POST' && url.pathname === GIT_SESSIONS_PATH;\n if (!isBranches && !isCreate) return undefined;\n const workspaceRoot = context.scope === 'workspace' ? context.workspaceRoot : undefined;\n if (workspaceRoot === undefined)\n return Response.json({ error: 'This route belongs to a workspace.' }, { status: 404 });\n if (isBranches) {\n const repositoryRoot = await git.repositoryRoot(workspaceRoot);\n const branches: GitBranchesResponse =\n repositoryRoot === undefined\n ? { repository: false, local: [], remote: [] }\n : { repository: true, ...(await git.listBranches(repositoryRoot)) };\n return Response.json(branches);\n }\n const parsed = newSessionRequest(await request.json().catch(() => undefined));\n if ('error' in parsed) return badRequest(parsed.error);\n const record = await operations.spawn(\n { cwd: workspaceRoot },\n {\n branch: parsed.branch,\n checkout: parsed.mode === 'existing-branch' ? 'existing' : 'new',\n ...(parsed.mode === 'existing-branch' && parsed.remote !== undefined ? { remote: parsed.remote } : {}),\n ...(parsed.mode === 'new-branch' && parsed.baseRef !== undefined ? { baseRef: parsed.baseRef } : {}),\n ...(parsed.name === undefined ? {} : { name: parsed.name }),\n },\n );\n publishLifecycle(record.sessionId, record.repositoryRoot);\n const created: GitSessionCreated = { sessionId: record.sessionId, worktreeId: record.id };\n return Response.json(created, { status: 201 });\n };\n\n /** The admitted root for a request, or a response explaining why not. */\n const rootOf = (url: URL): string | Response => {\n const repositoryId = url.searchParams.get('repositoryId');\n if (repositoryId === null || repositoryId === '') return badRequest('A repositoryId is required.');\n const root = context.resolveRepository?.(repositoryId);\n if (root === undefined) return badRequest('That repository is not admitted to this cockpit.');\n return root;\n };\n\n const homeDir = context.homeDirectory ?? os.homedir();\n const gitAuth = createGitAuthStore(homeDir);\n const branchDiff = createBranchDiff();\n\n /**\n * A workspace's remote auth. Workspace mounts only, so the step-up gate on\n * `PUT /api/workspaces/<id>/plugins/git/auth` is the one way to write it.\n * The view never carries the token.\n */\n const auth = async (request: Request, url: URL): Promise<Response | undefined> => {\n if (url.pathname !== GIT_AUTH_PATH) return undefined;\n if (context.scope !== 'workspace')\n return Response.json({ error: 'This route belongs to a workspace.' }, { status: 404 });\n if (request.method !== 'GET' && request.method !== 'PUT')\n return Response.json({ error: 'Use GET or PUT.' }, { status: 405 });\n const root = rootOf(url);\n if (root instanceof Response) return root;\n if (request.method === 'GET') return Response.json(gitAuth.view(root));\n try {\n return Response.json(gitAuth.save(root, await request.json().catch(() => undefined)));\n } catch (error) {\n // The settings page shows this next to the field, so it gets the plain\n // sentence and its recovery, not the tool-facing `[code]` form.\n if (error instanceof DoomGitExpectedError && error.code === 'invalid_request') {\n const text = error.message.replace(/^\\[[a-z_]+\\] /u, '').replace('\\nRecovery: ', ' ');\n return Response.json({ error: text, code: error.code }, { status: 400 });\n }\n throw error;\n }\n };\n\n /**\n * The session's change against its base. Session mounts only, rooted at the\n * session's own checkout; a file is served only when it is in the change set\n * computed for the same request.\n */\n const review = async (request: Request, url: URL): Promise<Response | undefined> => {\n if (url.pathname !== GIT_REVIEW_PATH && url.pathname !== GIT_REVIEW_FILE_PATH) return undefined;\n const cwd = context.scope === 'session' ? context.cwd : undefined;\n if (cwd === undefined) return Response.json({ error: 'This route belongs to a session.' }, { status: 404 });\n if (request.method !== 'GET') return Response.json({ error: 'Use GET.' }, { status: 405 });\n let recordedBaseRef: string | undefined;\n try {\n recordedBaseRef = createWorktreeRegistry(registryFile(cwd, homeDir))\n .list()\n .find((record) => record.sessionId === context.sessionId)?.baseRef;\n } catch {\n recordedBaseRef = undefined;\n }\n const result = await branchDiff.review(cwd, recordedBaseRef === undefined ? {} : { recordedBaseRef });\n if (url.pathname === GIT_REVIEW_PATH) {\n const outside: GitReviewSummary = { repository: false, files: [] };\n return Response.json(result?.summary ?? outside);\n }\n const filePath = url.searchParams.get('path') ?? '';\n if (result === undefined || !result.summary.files.some((file) => file.path === filePath)) {\n return Response.json({ error: 'That file is not part of this review.' }, { status: 404 });\n }\n return Response.json(await branchDiff.fileDiff(result, filePath));\n };\n\n return {\n async fetch(request) {\n const url = new URL(request.url);\n try {\n const answered =\n (await newSession(request, url)) ?? (await auth(request, url)) ?? (await review(request, url));\n if (answered !== undefined) return answered;\n } catch (error) {\n context.onNotice(`git request failed: ${(error as Error).name}`);\n return failed(error);\n }\n const root = rootOf(url);\n if (root instanceof Response) return root;\n // The operations layer works from a cwd, and an admitted repository\n // root is one.\n const callerContext = { cwd: root, sessionId: url.searchParams.get('sessionId') ?? '' };\n const isMutation =\n (request.method === 'POST' && url.pathname === '/worktrees') ||\n (request.method === 'DELETE' && /^\\/worktrees\\/[^/]+$/u.test(url.pathname));\n if (isMutation && callerContext.sessionId === '')\n return badRequest('A sessionId is required for worktree mutations.');\n\n try {\n if (request.method === 'GET' && url.pathname === '/worktrees') {\n return Response.json({ worktrees: await operations.list(callerContext) });\n }\n if (request.method === 'POST' && url.pathname === '/worktrees') {\n const body = (await request.json()) as { branch?: string; baseRef?: string; name?: string };\n if (typeof body.branch !== 'string' || body.branch.trim() === '') {\n return badRequest('A branch is required.');\n }\n const record = await operations.spawn(callerContext, {\n branch: body.branch,\n ...(body.baseRef === undefined ? {} : { baseRef: body.baseRef }),\n ...(body.name === undefined ? {} : { name: body.name }),\n });\n publishLifecycle(callerContext.sessionId, record.repositoryRoot);\n return Response.json({ worktree: record }, { status: 201 });\n }\n const closing = /^\\/worktrees\\/([^/]+)$/u.exec(url.pathname);\n if (request.method === 'DELETE' && closing) {\n const record = await operations.close(\n callerContext,\n decodeURIComponent(String(closing[1])),\n url.searchParams.get('force') === 'true',\n );\n publishLifecycle(callerContext.sessionId, record.repositoryRoot);\n return Response.json({ worktree: record });\n }\n return Response.json({ error: 'No such worktree route.' }, { status: 404 });\n } catch (error) {\n context.onNotice(`worktree request failed: ${(error as Error).name}`);\n return failed(error);\n }\n },\n close() {},\n };\n },\n};\n\nexport default api;\n","import { defineRoute } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/route.server';\n\nexport default defineRoute(contribution);\n","import { DoomGitExpectedError, type DoomGitErrorCode } from '../errors';\nimport { SETTINGS_HINT } from '../gitAuth';\nimport type { GitResult } from '../gitCli';\n\n/**\n * Turns a failed remote git call into an expected error a reader can act on.\n *\n * git's stderr is matched and then dropped. It never reaches a message, a\n * notice or a tool result, because a remote URL in it can carry a token. LC_ALL\n * is pinned to C by the runner, so these English phrases are the ones git\n * prints. Order matters: a 401 also says \"unable to access\", and auth must win.\n */\n\ninterface Rule {\n code: DoomGitErrorCode;\n phrases: readonly string[];\n message: string;\n recovery: string;\n retryable: boolean;\n}\n\nconst RULES: readonly Rule[] = [\n {\n code: 'host_key_changed',\n phrases: ['remote host identification has changed'],\n message: \"The remote's SSH host key changed since this machine last saw it.\",\n recovery: 'Check with the host that the change is expected, then update ~/.ssh/known_hosts from a terminal.',\n retryable: false,\n },\n {\n code: 'host_key_unknown',\n phrases: ['host key verification failed', 'no ed25519 host key is known', 'no rsa host key is known'],\n message: \"This machine does not trust the remote's SSH host key yet.\",\n recovery: 'Run `ssh -T git@<host>` once in a terminal and accept the key, then try again.',\n retryable: false,\n },\n {\n code: 'auth_failed',\n phrases: [\n 'authentication failed',\n 'could not read username',\n 'could not read password',\n 'permission denied (publickey',\n 'returned error: 401',\n 'returned error: 403',\n 'terminal prompts disabled',\n 'load key',\n 'unprotected private key',\n 'invalid format',\n ],\n message: 'The remote refused the credentials.',\n recovery: `Check this workspace's git remote auth. ${SETTINGS_HINT}`,\n retryable: false,\n },\n {\n code: 'repository_not_found',\n phrases: ['repository not found', 'does not appear to be a git repository'],\n message: 'The remote repository was not found, or these credentials cannot see it.',\n recovery: `Check the remote URL and that the credentials have access. ${SETTINGS_HINT}`,\n retryable: false,\n },\n {\n code: 'remote_unreachable',\n phrases: [\n 'could not resolve host',\n 'connection refused',\n 'connection timed out',\n 'operation timed out',\n 'unable to access',\n 'network is unreachable',\n ],\n message: 'The remote could not be reached.',\n recovery: 'Check the network and the remote URL, then try again.',\n retryable: true,\n },\n {\n code: 'push_lease_rejected',\n phrases: ['(stale info)'],\n message: 'The remote branch moved since your last fetch, so the force push was refused.',\n recovery: 'Pull to see the new commits, then decide whether to push again.',\n retryable: false,\n },\n {\n code: 'push_needs_force',\n phrases: ['(non-fast-forward)', '(fetch first)'],\n message: 'The remote branch has commits yours replaced, usually after a rebase.',\n recovery: 'Confirm a force push with lease, or pull first to keep the remote commits.',\n retryable: false,\n },\n {\n code: 'worktree_dirty',\n phrases: [\n 'unstaged changes',\n 'uncommitted changes',\n 'would be overwritten',\n 'your index contains uncommitted changes',\n ],\n message: 'There are uncommitted changes in the way.',\n recovery: 'Commit or stash your changes first.',\n retryable: false,\n },\n];\n\nexport function classifyGitFailure(operation: string, result: GitResult, mismatch?: string): DoomGitExpectedError {\n if (result.timedOut) {\n return new DoomGitExpectedError(\n 'git_timeout',\n `git ${operation} took too long and was stopped.`,\n true,\n 'Check the network, then try again.',\n );\n }\n const text = `${result.stderr}\\n${result.stdout}`.toLowerCase();\n const rule = RULES.find((candidate) => candidate.phrases.some((phrase) => text.includes(phrase)));\n if (rule === undefined) {\n return new DoomGitExpectedError(\n 'git_failed',\n `git ${operation} failed (exit ${String(result.code)}).`,\n false,\n 'Run the same command in a terminal in this checkout to see what git says.',\n );\n }\n const recovery =\n rule.code === 'auth_failed' && mismatch !== undefined ? `${mismatch} ${rule.recovery}` : rule.recovery;\n return new DoomGitExpectedError(rule.code, rule.message, rule.retryable, recovery);\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { resolveBaseRef } from '../branchDiff';\nimport { DoomGitExpectedError } from '../errors';\nimport { remoteEnv } from '../gitAuth';\nimport { NETWORK_TIMEOUT_MS, READ_TIMEOUT_MS, REBASE_TIMEOUT_MS, runGit } from '../gitCli';\nimport { classifyGitFailure } from '../gitFailure';\nimport type { GitSync, GitSyncContext, GitSyncOptions, GitSyncOutcome } from './type';\n\n/**\n * Manual pull, push and rebase for a session's checkout.\n *\n * DESIGN PATTERNS:\n * - The workspace's auth goes into the environment of the one fetch or push\n * that needs it, built fresh per call. Rebase itself runs locally and never\n * sees a credential.\n * - Fetch and rebase are separate commands, so a hung network can never leave a\n * rebase half applied.\n * - A conflicted rebase is not an error. It is left paused for the reader to\n * hand to the agent or abort, and git's own state reports it from then on.\n * - Pull and rebase refuse uncommitted tracked changes rather than stash them.\n * Untracked files only block when git says they would be overwritten.\n * - Push never forces on its own. A rejection comes back as `push_needs_force`,\n * and only a confirmed retry sends `--force-with-lease --force-if-includes`,\n * which git refuses if the remote holds commits this branch never integrated.\n */\n\nconst DONE: GitSyncOutcome = { outcome: 'done' };\n\nfunction expected(\n code: ConstructorParameters<typeof DoomGitExpectedError>[0],\n message: string,\n recovery: string,\n): DoomGitExpectedError {\n return new DoomGitExpectedError(code, message, false, recovery);\n}\n\nasync function readLine(cwd: string, args: readonly string[]): Promise<string | undefined> {\n const result = await runGit(cwd, args, { timeout: READ_TIMEOUT_MS });\n const out = result.stdout.trim();\n return result.code === 0 && out !== '' ? out : undefined;\n}\n\nasync function toplevel(cwd: string): Promise<string> {\n const root = await readLine(cwd, ['rev-parse', '--show-toplevel']);\n if (root === undefined)\n throw expected(\n 'not_a_repository',\n 'This session is not in a git checkout.',\n 'Open the session in a git repository.',\n );\n return root;\n}\n\nasync function rebasing(root: string): Promise<boolean> {\n for (const name of ['rebase-merge', 'rebase-apply']) {\n const gitPath = await readLine(root, ['rev-parse', '--git-path', name]);\n if (gitPath !== undefined && fs.existsSync(path.resolve(root, gitPath))) return true;\n }\n return false;\n}\n\nasync function conflicts(root: string): Promise<string[]> {\n const result = await runGit(root, ['diff', '--name-only', '--diff-filter=U', '-z'], { timeout: READ_TIMEOUT_MS });\n return result.stdout.split('\\0').filter((file) => file !== '');\n}\n\nasync function currentBranch(root: string): Promise<string> {\n const branch = await readLine(root, ['symbolic-ref', '--quiet', '--short', 'HEAD']);\n if (branch === undefined) {\n throw expected('detached_head', 'HEAD is detached, so there is no branch to sync.', 'Check out a branch first.');\n }\n return branch;\n}\n\nasync function guard(root: string, needsCleanTree: boolean): Promise<string> {\n if (await rebasing(root)) {\n throw expected(\n 'rebase_in_progress',\n 'A rebase is paused in this checkout.',\n 'Ask the agent to resolve it, or abort the rebase.',\n );\n }\n const branch = await currentBranch(root);\n if (needsCleanTree) {\n const dirty = await readLine(root, ['status', '--porcelain', '--untracked-files=no']);\n if (dirty !== undefined)\n throw expected('worktree_dirty', 'There are uncommitted changes.', 'Commit or stash your changes first.');\n }\n return branch;\n}\n\nexport function createGitSync(options: GitSyncOptions): GitSync {\n const baseEnv = options.baseEnv ?? process.env;\n\n /** One credentialed network command against `remote`, classified on failure. */\n const network = async (\n root: string,\n context: GitSyncContext,\n remote: string,\n operation: string,\n args: readonly string[],\n urlArgs: readonly string[] = [],\n ): Promise<void> => {\n const url = await readLine(root, ['remote', 'get-url', ...urlArgs, remote]);\n if (url === undefined)\n throw expected('no_remote', `There is no remote named ${remote}.`, 'Add the remote in a terminal first.');\n const prepared = remoteEnv(context.auth, url, baseEnv, options.homeDir);\n const result = await runGit(root, args, { timeout: NETWORK_TIMEOUT_MS, env: prepared.env });\n if (result.code !== 0) throw classifyGitFailure(operation, result, prepared.mismatch);\n };\n\n /** Rebases onto `onto`; a stop on conflicts leaves the rebase paused and says so. */\n const rebaseOnto = async (root: string, onto: string): Promise<GitSyncOutcome> => {\n const result = await runGit(root, ['rebase', onto], {\n timeout: REBASE_TIMEOUT_MS,\n env: { ...baseEnv, GIT_EDITOR: 'true', GIT_TERMINAL_PROMPT: '0' },\n });\n if (result.code === 0) return DONE;\n if (await rebasing(root)) return { outcome: 'paused', conflicts: await conflicts(root) };\n throw classifyGitFailure('rebase', result);\n };\n\n /** The remote a ref like `origin/main` or `refs/remotes/origin/main` belongs to. */\n const remoteOfRef = async (root: string, ref: string): Promise<string | undefined> => {\n const full = await readLine(root, ['rev-parse', '--symbolic-full-name', ref]);\n if (full === undefined || !full.startsWith('refs/remotes/')) return undefined;\n const rest = full.slice('refs/remotes/'.length);\n const cut = rest.indexOf('/');\n return cut > 0 ? rest.slice(0, cut) : undefined;\n };\n\n return {\n async pull(context) {\n const root = await toplevel(context.cwd);\n const branch = await guard(root, true);\n const remote = await readLine(root, ['config', `branch.${branch}.remote`]);\n const upstream = await readLine(root, [\n 'rev-parse',\n '--abbrev-ref',\n '--symbolic-full-name',\n `${branch}@{upstream}`,\n ]);\n if (remote === undefined || upstream === undefined) {\n throw expected('no_upstream', `${branch} has no upstream to pull from.`, 'Push once to set an upstream.');\n }\n // A branch tracking another local branch has nothing to fetch.\n if (remote !== '.') await network(root, context, remote, 'fetch', ['fetch', '--prune', remote]);\n return rebaseOnto(root, upstream);\n },\n\n async push(context, force) {\n const root = await toplevel(context.cwd);\n const branch = await guard(root, false);\n const configuredRemote = await readLine(root, ['config', `branch.${branch}.remote`]);\n const merge = await readLine(root, ['config', `branch.${branch}.merge`]);\n let remote = configuredRemote;\n let target = merge;\n const args = ['push', '--porcelain'];\n if (remote === undefined || target === undefined || remote === '.') {\n const remotes = ((await readLine(root, ['remote'])) ?? '').split('\\n').filter((name) => name !== '');\n remote = remotes.includes('origin') ? 'origin' : remotes.length === 1 ? remotes[0] : undefined;\n if (remote === undefined) {\n throw expected(\n 'no_remote',\n 'There is no remote to push to.',\n remotes.length === 0\n ? 'Add a remote in a terminal first.'\n : 'Push once from a terminal to choose the remote.',\n );\n }\n target = `refs/heads/${branch}`;\n args.push('--set-upstream');\n }\n if (force) args.push(`--force-with-lease=${target}`, '--force-if-includes');\n args.push(remote, `HEAD:${target}`);\n await network(root, context, remote, 'push', args, ['--push']);\n return DONE;\n },\n\n async rebase(context) {\n const root = await toplevel(context.cwd);\n const branch = await guard(root, true);\n const base = await resolveBaseRef(root, branch, context.recordedBaseRef);\n if (base === undefined)\n throw expected(\n 'no_base',\n 'No base branch to rebase onto.',\n 'Fetch the remote, or create the worktree from a base.',\n );\n const remote = await remoteOfRef(root, base);\n if (remote !== undefined) await network(root, context, remote, 'fetch', ['fetch', '--prune', remote]);\n return rebaseOnto(root, base);\n },\n\n async abortRebase(context) {\n const root = await toplevel(context.cwd);\n if (!(await rebasing(root))) return DONE;\n const result = await runGit(root, ['rebase', '--abort'], { timeout: REBASE_TIMEOUT_MS });\n if (result.code !== 0) throw classifyGitFailure('rebase --abort', result);\n return DONE;\n },\n };\n}\n","/**\n * The cockpit's view of what this session changed against its base: the counts\n * the '# diff' group shows, what the review tab lists and draws, and the manual\n * sync that sits beside them.\n *\n * DESIGN PATTERNS:\n * - Declarations only, shared by the hub and the page.\n * - Its own channel, apart from worktrees. Worktrees are repository\n * management; the diff is this session's code change.\n * - A diff row carries one line number whose file follows from its marker: the\n * new file's for context and additions, the old file's for removals. It is\n * the same shape the shared DiffView draws.\n *\n * AVOID:\n * - Behaviour or node builtins. Browser code imports this file.\n */\n\n/** The session channel carrying this checkout's changes and the sync around them. */\nexport const GIT_CHANGES_TYPE = 'git_changes';\n\n/** The sync actions the review tab offers. */\nexport type GitSyncAction = 'pull' | 'push' | 'rebase' | 'abort-rebase';\n\n/** What the review tab asks the hub to run. `force` only follows a confirmed rejected push. */\nexport type GitChangesCommand =\n | { action: 'pull' }\n | { action: 'push'; force?: true }\n | { action: 'rebase' }\n | { action: 'abort-rebase' };\n\nexport type GitSyncErrorTarget =\n | { action: 'pull' | 'rebase' | 'abort-rebase' }\n /** A push the remote rejected as non-fast-forward; the tab offers a lease force after a confirm. */\n | { action: 'push'; forceRequired?: true };\n\nexport interface GitChangesPayload {\n /** Absent outside a git checkout. */\n changes?: GitChangesView;\n /** Label of the sync command in flight. */\n pending?: string;\n /** The last sync failure, cleared when the next command starts. */\n error?: string;\n errorTarget?: GitSyncErrorTarget;\n}\n\n/** What the session changed since its base, as the '# diff' lane and the review header show it. */\nexport interface GitChangesView {\n /** The checked-out branch; absent on a detached HEAD. */\n branch?: string;\n /** The ref the changes are measured against; absent when none resolved, so only uncommitted work counts. */\n base?: string;\n added: number;\n removed: number;\n files: number;\n /** More files changed than were counted. */\n truncated?: boolean;\n /** The branch's upstream and how far apart the two are. */\n upstream?: { ref: string; ahead: number; behind: number };\n /** Present while a rebase is paused on conflicts. */\n rebase?: { conflicts: string[] };\n}\n\nexport type GitReviewFileStatus = 'added' | 'modified' | 'deleted' | 'untracked' | 'conflicted';\n\n/** One changed file in the review list. */\nexport interface GitReviewFileEntry {\n /** Repository-relative, forward slashes. */\n path: string;\n status: GitReviewFileStatus;\n added: number;\n removed: number;\n binary?: boolean;\n}\n\n/** The review tab's file list. */\nexport interface GitReviewSummary {\n /** False when the session's directory is not a git checkout. */\n repository: boolean;\n branch?: string;\n base?: string;\n /** Short sha of the commit the diff starts from. */\n mergeBase?: string;\n files: GitReviewFileEntry[];\n truncated?: boolean;\n}\n\nexport interface GitDiffRow {\n marker: '+' | '-' | ' ';\n line: number;\n content: string;\n}\n\nexport interface GitDiffHunk {\n start: number;\n rows: GitDiffRow[];\n}\n\n/** One file's hunks, fetched when the reader expands it. */\nexport interface GitReviewFileDiff {\n path: string;\n hunks: GitDiffHunk[];\n binary?: true;\n /** The diff was past the size cap and is not drawn. */\n tooLarge?: true;\n}\n","/**\n * The '# diff' data channel: this session's change against its base, and the\n * manual sync commands the review tab sends back through it.\n *\n * DESIGN PATTERNS:\n * - Apart from the worktrees channel. Worktrees are repository management;\n * this is the session's own code change.\n * - Push, not poll. The session facet publishes a \"changed\" event after every\n * tool call and settled turn; recounts are coalesced to one in flight plus\n * one rerun, so a burst of tool calls costs at most two.\n * - One sync command per session. A rebase and a push must never overlap.\n * - Auth is read fresh for each command from the session's workspace, and goes\n * only into that command's git child.\n *\n * AVOID:\n * - Echoing git output. Failures go through classifyGitFailure, which matches\n * stderr and drops it, because a remote URL in it can carry a token.\n */\nimport os from 'node:os';\n\nimport type { DoomHubChannel, DoomHubChannelSource, DoomHubSessionScope } from '@agimon-ai/doompi-core/hubChannel';\n\nimport { createBranchDiff } from '../../../../services/branchDiff';\nimport type { BranchDiff } from '../../../../services/branchDiff/type';\nimport { DoomGitExpectedError } from '../../../../services/errors';\nimport { createGitAuthStore } from '../../../../services/gitAuth';\nimport type { GitAuthStore } from '../../../../services/gitAuth/type';\nimport { createGitSync } from '../../../../services/gitSync';\nimport type { GitSync, GitSyncOutcome } from '../../../../services/gitSync/type';\nimport { registryFile } from '../../../../services/paths';\nimport { GIT_SESSION_CHANGED_EVENT, isSessionChangedEvent } from '../../../../services/worktreeEvents';\nimport { createWorktreeRegistry } from '../../../../services/worktreeRegistry';\nimport {\n GIT_CHANGES_TYPE,\n type GitChangesCommand,\n type GitChangesPayload,\n type GitChangesView,\n type GitSyncErrorTarget,\n} from '../../../../types/gitReview';\n\ninterface SessionState {\n changes: GitChangesView | undefined;\n pending: string | undefined;\n error: string | undefined;\n errorTarget: GitSyncErrorTarget | undefined;\n}\n\n/** What the channel needs from its surroundings, injected so tests stay off this machine's home. */\nexport interface GitChangesChannelOptions {\n homeDir?: string;\n diff?: BranchDiff;\n sync?: GitSync;\n auth?: GitAuthStore;\n}\n\nfunction payloadOf(state: SessionState): GitChangesPayload {\n return {\n ...(state.changes === undefined ? {} : { changes: state.changes }),\n ...(state.pending === undefined ? {} : { pending: state.pending }),\n ...(state.error === undefined ? {} : { error: state.error }),\n ...(state.errorTarget === undefined ? {} : { errorTarget: state.errorTarget }),\n };\n}\n\n/** A command the page sent, or undefined when the frame was not one. */\nexport function parseChangesCommand(payload: unknown): GitChangesCommand | undefined {\n if (typeof payload !== 'object' || payload === null) return undefined;\n const value = payload as Record<string, unknown>;\n if (value.action === 'pull' || value.action === 'rebase' || value.action === 'abort-rebase')\n return { action: value.action };\n if (value.action === 'push') return value.force === true ? { action: 'push', force: true } : { action: 'push' };\n return undefined;\n}\n\nconst PENDING: Readonly<Record<GitChangesCommand['action'], string>> = {\n pull: 'pulling…',\n push: 'pushing…',\n rebase: 'rebasing…',\n 'abort-rebase': 'aborting the rebase…',\n};\n\n/** The error target a failure maps to: a rejected plain push asks for a confirmed lease force. */\nfunction errorTargetFor(command: GitChangesCommand, error: unknown): GitSyncErrorTarget {\n if (command.action !== 'push') return { action: command.action };\n const needsForce =\n error instanceof DoomGitExpectedError && error.code === 'push_needs_force' && command.force !== true;\n return needsForce ? { action: 'push', forceRequired: true } : { action: 'push' };\n}\n\nfunction failureText(error: unknown): string {\n // The expected error's message carries its own `[code]` prefix and recovery\n // line; the page shows the human part.\n if (error instanceof DoomGitExpectedError)\n return error.message.replace(/^\\[[a-z_]+\\] /u, '').replace('\\nRecovery: ', ' ');\n return 'The git command failed.';\n}\n\nexport function createGitChangesChannel(options: GitChangesChannelOptions = {}): DoomHubChannel {\n let receiveCommand: ((scope: DoomHubSessionScope, payload: unknown) => void) | undefined;\n\n return {\n frameType: GIT_CHANGES_TYPE,\n start(host) {\n const homeDir = options.homeDir ?? os.homedir();\n const diff = options.diff ?? createBranchDiff();\n const sync = options.sync ?? createGitSync({ homeDir });\n const auth = options.auth ?? createGitAuthStore(homeDir);\n const latest = new Map<string, SessionState>();\n const subscriptions = new Map<string, () => void>();\n const scopes = new Map<string, DoomHubSessionScope>();\n const inFlight = new Set<string>();\n const rerun = new Set<string>();\n const busy = new Set<string>();\n\n /** The base the session's own worktree was created from, when it has one. */\n const recordedBaseRef = (scope: DoomHubSessionScope): string | undefined => {\n try {\n return createWorktreeRegistry(registryFile(scope.cwd, homeDir))\n .list()\n .find((record) => record.sessionId === scope.sessionId)?.baseRef;\n } catch {\n return undefined;\n }\n };\n\n /** Republishes a session, skipping a frame that would say nothing new. */\n const publish = (sessionId: string, next: SessionState): void => {\n const previous = latest.get(sessionId);\n latest.set(sessionId, next);\n if (previous !== undefined && JSON.stringify(payloadOf(previous)) === JSON.stringify(payloadOf(next))) return;\n host.publish(sessionId, payloadOf(next));\n };\n\n const update = (sessionId: string, patch: Partial<SessionState>): void => {\n const previous = latest.get(sessionId) ?? {\n changes: undefined,\n pending: undefined,\n error: undefined,\n errorTarget: undefined,\n };\n publish(sessionId, { ...previous, ...patch });\n };\n\n /** Recounts one session; a request while one runs schedules exactly one more. */\n const refresh = (sessionId: string): void => {\n const scope = scopes.get(sessionId);\n if (scope === undefined) return;\n if (inFlight.has(sessionId)) {\n rerun.add(sessionId);\n return;\n }\n inFlight.add(sessionId);\n const base = recordedBaseRef(scope);\n void diff\n .review(scope.cwd, base === undefined ? {} : { recordedBaseRef: base })\n .then((review) => {\n if (scopes.has(sessionId)) update(sessionId, { changes: review?.changes });\n })\n .catch((error: unknown) => {\n host.onNotice(\n `git diff refresh failed for ${sessionId} (${error instanceof Error ? error.name : 'unknown'})`,\n );\n })\n .finally(() => {\n inFlight.delete(sessionId);\n if (rerun.delete(sessionId)) refresh(sessionId);\n });\n };\n\n const run = (scope: DoomHubSessionScope, command: GitChangesCommand): Promise<GitSyncOutcome> => {\n const workspaceRoot = scope.sessionContext?.workspaceRoot ?? scope.cwd;\n const base = recordedBaseRef(scope);\n const context = {\n cwd: scope.cwd,\n auth: auth.read(workspaceRoot),\n ...(base === undefined ? {} : { recordedBaseRef: base }),\n };\n if (command.action === 'pull') return sync.pull(context);\n if (command.action === 'push') return sync.push(context, command.force === true);\n if (command.action === 'rebase') return sync.rebase(context);\n return sync.abortRebase(context);\n };\n\n const source: DoomHubChannelSource = {\n payloadFor(scope) {\n const state = latest.get(scope.sessionId);\n return state === undefined ? undefined : payloadOf(state);\n },\n sessionAdded(scope) {\n scopes.set(scope.sessionId, scope);\n refresh(scope.sessionId);\n const unsubscribe = host.directEvents.subscribe(GIT_SESSION_CHANGED_EVENT, scope.sessionId, (payload) => {\n if (isSessionChangedEvent(payload)) refresh(scope.sessionId);\n });\n subscriptions.set(scope.sessionId, unsubscribe);\n },\n sessionRemoved(sessionId) {\n subscriptions.get(sessionId)?.();\n subscriptions.delete(sessionId);\n scopes.delete(sessionId);\n latest.delete(sessionId);\n rerun.delete(sessionId);\n busy.delete(sessionId);\n },\n close() {\n for (const unsubscribe of subscriptions.values()) unsubscribe();\n subscriptions.clear();\n scopes.clear();\n latest.clear();\n rerun.clear();\n busy.clear();\n },\n };\n\n receiveCommand = (scope, payload) => {\n const command = parseChangesCommand(payload);\n if (command === undefined || !scopes.has(scope.sessionId)) return;\n if (busy.has(scope.sessionId)) return;\n busy.add(scope.sessionId);\n update(scope.sessionId, { pending: PENDING[command.action], error: undefined, errorTarget: undefined });\n void run(scope, command)\n .then(() => update(scope.sessionId, { pending: undefined }))\n .catch((error: unknown) => {\n host.onNotice(\n `git ${command.action} failed for ${scope.sessionId} (${error instanceof DoomGitExpectedError ? error.code : 'unexpected'})`,\n );\n update(scope.sessionId, {\n pending: undefined,\n error: failureText(error),\n errorTarget: errorTargetFor(command, error),\n });\n })\n .finally(() => {\n busy.delete(scope.sessionId);\n // A paused rebase, a moved upstream and new commits all show in the recount.\n refresh(scope.sessionId);\n });\n };\n\n return source;\n },\n receive(scope, payload) {\n receiveCommand?.(scope, payload);\n },\n };\n}\n\nexport default createGitChangesChannel;\n","import { defineChannel } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/git-changes.server';\n\nexport default defineChannel(contribution);\n","/**\n * The cockpit's view of this session's worktrees.\n *\n * DESIGN PATTERNS:\n * - Declarations only. The channel frame type is a constant so the hub and the\n * page cannot drift apart on a string.\n * - A view is the subset of a record the dock needs, not the record. The\n * registry may hold paths and provenance the page has no business rendering.\n *\n * AVOID:\n * - Adding behaviour here. This file is imported by browser code, so it must\n * stay free of node builtins.\n */\n\n/** The data channel carrying one session's worktrees to the page. */\nexport const GIT_WORKTREES_TYPE = 'git_worktrees';\n\n/** One worktree, as the activity dock and its panel render it. */\nexport interface WorktreeView {\n id: string;\n branch: string;\n path: string;\n /** The session the hub started for this worktree, when it is still live. */\n sessionId: string | null;\n /** True once the directory the record names has gone missing. */\n orphaned: boolean;\n /**\n * True when the session that asked for this worktree is gone.\n *\n * An owned worktree is only ever shown to its own session. This flag marks\n * the exception: once the parent is dead nobody would see the worktree at\n * all, so every session in the repository does, and may close it.\n */\n unowned: boolean;\n}\n\n/**\n * What the panel asks the hub channel to do.\n *\n * The dock acts through its own channel rather than through the agent: a\n * worktree made from the panel and one made by the tool take the same\n * `worktreeOperations` path, but the panel no longer has to spend a turn of\n * the conversation to get there.\n */\nexport type GitWorktreesCommand =\n | { action: 'create'; branch: string; baseRef?: string; reservationId?: string }\n | { action: 'close'; id: string; force?: boolean };\n\nexport type WorktreeErrorTarget = { action: 'create' } | { action: 'close'; id: string };\n\nexport interface GitWorktreesPayload {\n worktrees: WorktreeView[];\n /** Label of the operation in flight, absent when the session is idle. */\n pending?: string;\n /** The last failure, cleared when the next command starts. */\n error?: string;\n /** The operation that produced the last failure, when known. */\n errorTarget?: WorktreeErrorTarget;\n}\n","/**\n * The worktrees data channel, and the commands the dock sends back through it.\n *\n * The registry is durable state only. Live lifecycle changes arrive through the\n * hub-owned direct event bus, so this channel never polls or claims files.\n */\nimport type {\n DoomHubChannel,\n DoomHubChannelSource,\n DoomHubSessionScope,\n DoomHubSessionService,\n} from '@agimon-ai/doompi-core/hubChannel';\n\nimport { DoomGitExpectedError, HubUnavailableError } from '../../../../services/errors';\nimport { createWorktreeGit } from '../../../../services/gitCli';\nimport { registryFile } from '../../../../services/paths';\nimport { GIT_WORKTREE_LIFECYCLE_EVENT, isWorktreeLifecycleEvent } from '../../../../services/worktreeEvents';\nimport { createWorktreeOperations, type WorktreeOperations } from '../../../../services/worktreeOperations';\nimport { createWorktreeRegistry } from '../../../../services/worktreeRegistry';\nimport {\n GIT_WORKTREES_TYPE,\n type GitWorktreesCommand,\n type WorktreeErrorTarget,\n type WorktreeView,\n} from '../../../../types/webWorktrees';\n\ninterface SessionState {\n worktrees: WorktreeView[];\n pending: string | undefined;\n error: string | undefined;\n errorTarget: WorktreeErrorTarget | undefined;\n}\n\nfunction payloadOf(state: SessionState): Record<string, unknown> {\n return {\n worktrees: state.worktrees,\n ...(state.pending === undefined ? {} : { pending: state.pending }),\n ...(state.error === undefined ? {} : { error: state.error }),\n ...(state.errorTarget === undefined ? {} : { errorTarget: state.errorTarget }),\n };\n}\n\n/** What the channel needs from its surroundings, injected so tests stay off this machine. */\nexport interface WorktreesChannelOptions {\n operations?: WorktreeOperations;\n homeDir?: string;\n}\n\ninterface ViewDeps {\n homeDir: string | undefined;\n sessionService: DoomHubSessionService;\n}\n\n/** Worktrees visible to this session, using the hub's live session table for ownership. */\nfunction viewsFor(scope: DoomHubSessionScope, deps: ViewDeps): WorktreeView[] {\n try {\n return createWorktreeRegistry(registryFile(scope.cwd, deps.homeDir))\n .list()\n .flatMap((record) => {\n // A worktree opened on its own from the new-session dialog belongs to the session\n // inside it; sibling sessions in the repository never see it.\n if (record.parentSessionId === undefined && record.sessionId !== scope.sessionId) return [];\n const owned = record.parentSessionId === undefined || record.parentSessionId === scope.sessionId;\n const unowned = !owned && !deps.sessionService.isLive(record.parentSessionId!);\n if (!owned && !unowned) return [];\n return [\n {\n id: record.id,\n branch: record.branch,\n path: record.path,\n sessionId: record.status === 'orphaned' ? null : record.sessionId,\n orphaned: record.status === 'orphaned',\n unowned,\n },\n ];\n });\n } catch {\n return [];\n }\n}\n\nfunction sameList(left: readonly WorktreeView[], right: readonly WorktreeView[]): boolean {\n if (left.length !== right.length) return false;\n return left.every((entry, index) => {\n const other = right[index];\n return (\n other !== undefined &&\n entry.id === other.id &&\n entry.branch === other.branch &&\n entry.sessionId === other.sessionId &&\n entry.orphaned === other.orphaned &&\n entry.unowned === other.unowned\n );\n });\n}\n\nfunction errorTargetFor(command: GitWorktreesCommand): WorktreeErrorTarget {\n return command.action === 'create' ? { action: 'create' } : { action: 'close', id: command.id };\n}\n\n/** A command the page sent, or undefined when the frame was not one. */\nfunction parseCommand(payload: unknown): GitWorktreesCommand | undefined {\n if (typeof payload !== 'object' || payload === null) return undefined;\n const value = payload as Record<string, unknown>;\n if (value.action === 'create') {\n if (typeof value.branch !== 'string' || value.branch.trim() === '') return undefined;\n if (\n value.reservationId !== undefined &&\n (typeof value.reservationId !== 'string' || !/^[A-Za-z0-9_-]+$/u.test(value.reservationId))\n )\n return undefined;\n return {\n action: 'create',\n branch: value.branch.trim(),\n ...(typeof value.baseRef === 'string' && value.baseRef.trim() !== '' ? { baseRef: value.baseRef.trim() } : {}),\n ...(typeof value.reservationId === 'string' ? { reservationId: value.reservationId } : {}),\n };\n }\n if (value.action === 'close') {\n if (typeof value.id !== 'string' || value.id === '') return undefined;\n return { action: 'close', id: value.id, ...(value.force === true ? { force: true } : {}) };\n }\n return undefined;\n}\n\n/**\n * What the reader is told when a command fails.\n *\n * An expected failure explains itself. Anything else is summarised, never\n * echoed: a git error can carry a remote URL with a token in it.\n */\nfunction failureText(error: unknown): string {\n return error instanceof DoomGitExpectedError ? error.message : 'The worktree operation failed.';\n}\n\n/** Starts one direct-event subscription per managed session. */\nexport function createWorktreesChannel(options: WorktreesChannelOptions = {}): DoomHubChannel {\n // Assigned by start, because receive is reachable only while the channel is\n // running and the command needs the state the direct event subscriptions keep.\n let receiveCommand: ((scope: DoomHubSessionScope, payload: unknown) => void) | undefined;\n\n return {\n frameType: GIT_WORKTREES_TYPE,\n start(host) {\n const sessionService = host.sessionService;\n if (sessionService === undefined) {\n throw new HubUnavailableError('The cockpit session service is unavailable. Start the cockpit and try again.');\n }\n const worktrees =\n options.operations ??\n createWorktreeOperations({\n git: createWorktreeGit(),\n sessionService,\n });\n /** Announces a successful mutation to this session's lifecycle subscribers. */\n const publishLifecycle = (scope: DoomHubSessionScope, repositoryRoot: string): void => {\n host.directEvents.publish(GIT_WORKTREE_LIFECYCLE_EVENT, scope.sessionId, {\n version: 1,\n repositoryRoot,\n });\n };\n const unregisterWorktreeProvisioner = sessionService.registerReservedWorktreeProvisioner?.(\n async ({ reservationId, parentSessionId, signal }) => {\n const parent = host.sessions().find((scope) => scope.sessionId === parentSessionId);\n if (parent === undefined) throw new Error('The conversation parent session is unavailable.');\n const branch = `doompi/conversation-${reservationId.slice(0, 12)}`;\n const record = await worktrees.spawn(\n { cwd: parent.cwd, sessionId: parent.sessionId },\n { branch, name: `conversation ${reservationId.slice(0, 8)}`, reservationId },\n { signal },\n );\n const reservations = sessionService.reservations;\n if (reservations === undefined) throw new Error('Conversation reservations are unavailable.');\n const session = await reservations.complete(reservationId, parentSessionId);\n publishLifecycle(parent, record.repositoryRoot);\n return session;\n },\n );\n const views: ViewDeps = { homeDir: options.homeDir, sessionService };\n const latest = new Map<string, SessionState>();\n const subscriptions = new Map<string, () => void>();\n const busy = new Set<string>();\n const generations = new Map<string, symbol>();\n const newGeneration = (sessionId: string): symbol => {\n const generation = Symbol(sessionId);\n generations.set(sessionId, generation);\n return generation;\n };\n\n /** Republishes a session, skipping a frame that would say nothing new. */\n const publish = (scope: DoomHubSessionScope, force: boolean): void => {\n const previous = latest.get(scope.sessionId);\n const next: SessionState = {\n worktrees: viewsFor(scope, views),\n pending: previous?.pending,\n error: previous?.error,\n errorTarget: previous?.errorTarget,\n };\n if (\n !force &&\n previous !== undefined &&\n sameList(previous.worktrees, next.worktrees) &&\n previous.pending === next.pending &&\n previous.error === next.error &&\n previous.errorTarget === next.errorTarget\n ) {\n return;\n }\n latest.set(scope.sessionId, next);\n host.publish(scope.sessionId, payloadOf(next));\n };\n\n const mark = (\n scope: DoomHubSessionScope,\n pending: string | undefined,\n error: string | undefined,\n errorTarget: WorktreeErrorTarget | undefined,\n ): void => {\n const previous = latest.get(scope.sessionId);\n latest.set(scope.sessionId, {\n worktrees: previous?.worktrees ?? viewsFor(scope, views),\n pending,\n error,\n errorTarget,\n });\n publish(scope, true);\n };\n\n const run = async (\n scope: DoomHubSessionScope,\n command: GitWorktreesCommand,\n generation: symbol,\n ): Promise<void> => {\n const context = { cwd: scope.cwd, sessionId: scope.sessionId };\n const markCurrent = (\n pending: string | undefined,\n error: string | undefined,\n errorTarget: WorktreeErrorTarget | undefined,\n ): void => {\n if (generations.get(scope.sessionId) !== generation) return;\n mark(scope, pending, error, errorTarget);\n };\n if (command.action === 'create') {\n markCurrent(`creating ${command.branch}…`, undefined, undefined);\n const record = await worktrees.spawn(\n context,\n {\n branch: command.branch,\n ...(command.baseRef === undefined ? {} : { baseRef: command.baseRef }),\n ...(command.reservationId === undefined ? {} : { reservationId: command.reservationId }),\n },\n // Each phase replaces the label, so the panel says what is\n // happening instead of holding one line for the whole wait.\n { onProgress: (label) => markCurrent(label, undefined, undefined) },\n );\n if (generations.get(scope.sessionId) !== generation) return;\n publishLifecycle(scope, record.repositoryRoot);\n return;\n }\n markCurrent(`closing ${command.id}…`, undefined, undefined);\n const record = await worktrees.close(context, command.id, command.force ?? false);\n if (generations.get(scope.sessionId) !== generation) return;\n publishLifecycle(scope, record.repositoryRoot);\n };\n\n const source: DoomHubChannelSource = {\n payloadFor(scope) {\n const state = latest.get(scope.sessionId);\n return state === undefined ? undefined : payloadOf(state);\n },\n sessionAdded(scope) {\n newGeneration(scope.sessionId);\n publish(scope, false);\n const unsubscribe = host.directEvents.subscribe(GIT_WORKTREE_LIFECYCLE_EVENT, scope.sessionId, (payload) => {\n if (!isWorktreeLifecycleEvent(payload)) return;\n let sameRepository = false;\n try {\n sameRepository =\n registryFile(scope.cwd, options.homeDir) === registryFile(payload.repositoryRoot, options.homeDir);\n } catch {\n sameRepository = false;\n }\n if (sameRepository) publish(scope, false);\n });\n subscriptions.set(scope.sessionId, unsubscribe);\n },\n sessionRemoved(sessionId) {\n newGeneration(sessionId);\n subscriptions.get(sessionId)?.();\n subscriptions.delete(sessionId);\n latest.delete(sessionId);\n busy.delete(sessionId);\n },\n close() {\n unregisterWorktreeProvisioner?.();\n for (const unsubscribe of subscriptions.values()) unsubscribe();\n subscriptions.clear();\n latest.clear();\n busy.clear();\n generations.clear();\n },\n };\n receiveCommand = (scope, payload) => {\n const command = parseCommand(payload);\n if (command === undefined) return;\n // One operation per session. A create runs for minutes, and a second\n // click must not start a second worktree behind the first.\n if (busy.has(scope.sessionId)) return;\n const generation = generations.get(scope.sessionId);\n if (generation === undefined) return;\n busy.add(scope.sessionId);\n void run(scope, command, generation)\n .then(() => {\n if (generations.get(scope.sessionId) !== generation) return;\n mark(scope, undefined, undefined, undefined);\n })\n .catch((error: unknown) => {\n if (generations.get(scope.sessionId) !== generation) return;\n host.onNotice(`worktree command failed for ${scope.sessionId} (${failureText(error)})`);\n mark(scope, undefined, failureText(error), errorTargetFor(command));\n })\n .finally(() => {\n if (generations.get(scope.sessionId) === generation) busy.delete(scope.sessionId);\n });\n };\n\n return source;\n },\n receive(scope, payload) {\n receiveCommand?.(scope, payload);\n },\n };\n}\n\nexport default createWorktreesChannel;\n","import { defineChannel } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/git-worktrees.server';\n\nexport default defineChannel(contribution);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../_lib/root.server';\n\nexport default defineHook((context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.hooks[1]!);\n","import { defineHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../_lib/root.server';\n\nexport default defineHook((context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.hooks[0]!);\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../../_lib/root.server';\n\nexport default (context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.resources[0]!;\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/doompiGit.server';\n\nexport default defineResource(contribution);\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../../_lib/root.server';\n\nexport default (context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.resources[2]!;\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/doompiGitReadme.server';\n\nexport default defineResource(contribution);\n","import type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../../_lib/root.server';\n\nexport default (context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.resources[1]!;\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport contribution from './_lib/doompiUseGit.server';\n\nexport default defineResource(contribution);\n","import { defineServerTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport type { GitServerScope } from '../_lib/root.server';\n\nexport default defineServerTool((context: WithRoot<DoomServerPluginContext, GitServerScope>) => context.root.tool);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport apiRoute from '../src/extensions/(backend)/api/git/route.server';\nimport channelGitChanges from '../src/extensions/(backend)/channel/git-changes.server';\nimport channelGitWorktrees from '../src/extensions/(backend)/channel/git-worktrees.server';\nimport hookAgentSettled from '../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.server';\nimport hookToolExecutionEnd from '../src/extensions/workspaces/sessions/(backend)/hook/tool-execution-end.server';\nimport resourceDoompiGit from '../src/extensions/workspaces/sessions/(backend)/resource/doompiGit.server';\nimport resourceDoompiGitReadme from '../src/extensions/workspaces/sessions/(backend)/resource/doompiGitReadme.server';\nimport resourceDoompiUseGit from '../src/extensions/workspaces/sessions/(backend)/resource/doompiUseGit.server';\nimport toolRunWorktree from '../src/extensions/workspaces/sessions/(backend)/tool/runWorktree.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const facet = defineServerPlugin({\n name: '@agimon-ai/doompi-git',\n global: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'git_changes' }, channelGitChanges()), () => via({ frameType: 'git_worktrees' }, channelGitWorktrees())]; },\n }),\n workspace: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'git_changes' }, channelGitChanges()), () => via({ frameType: 'git_worktrees' }, channelGitWorktrees())]; },\n }),\n session: async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'git_changes' }, channelGitChanges()), () => via({ frameType: 'git_worktrees' }, channelGitWorktrees())]; },\n get hooks(): DoomServerSessionPlugin['hooks'] { return [via({ event: 'agent_settled' }, at(hookAgentSettled, contextSession)), via({ event: 'tool_execution_end' }, at(hookToolExecutionEnd, contextSession))]; },\n get resources(): DoomServerSessionPlugin['resources'] { return [at(resourceDoompiGit, contextSession), at(resourceDoompiGitReadme, contextSession), at(resourceDoompiUseGit, contextSession)]; },\n get tools(): DoomServerSessionPlugin['tools'] { return [via({ name: 'run_worktree' }, at(toolRunWorktree, contextSession))]; },\n services: [...(scopeSession.services ?? [])],\n get activities(): DoomServerSessionPlugin['activities'] { return [...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default facet;\n"],"mappings":"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"}