@agimon-ai/doompi-git 0.0.1-alpha.8 → 0.0.1-alpha.9
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.
- package/dist/_virtual/_rolldown/runtime.cjs +23 -1
- package/dist/api-contracts.cjs +7 -1
- package/dist/api-contracts.d.cts +1 -1
- package/dist/api-contracts.d.mts +1 -1
- package/dist/api-contracts.mjs +2 -1
- package/dist/extensions/pi.cjs +38 -1
- package/dist/extensions/pi.cjs.map +1 -1
- package/dist/extensions/pi.d.cts +5 -4
- package/dist/extensions/pi.d.cts.map +1 -1
- package/dist/extensions/pi.d.mts +5 -4
- package/dist/extensions/pi.d.mts.map +1 -1
- package/dist/extensions/pi.mjs +33 -1
- package/dist/extensions/pi.mjs.map +1 -1
- package/dist/extensions/server.cjs +72 -1
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.d.cts +3 -3
- package/dist/extensions/server.d.cts.map +1 -1
- package/dist/extensions/server.d.mts +3 -3
- package/dist/extensions/server.d.mts.map +1 -1
- package/dist/extensions/server.mjs +67 -1
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/extensions/web.mjs +485 -0
- package/dist/extensions/web.mjs.map +1 -0
- package/dist/index.cjs +5 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +3 -1
- package/dist/src/constants/git.cjs +8 -0
- package/dist/src/constants/git.cjs.map +1 -0
- package/dist/src/constants/git.mjs +7 -0
- package/dist/src/constants/git.mjs.map +1 -0
- package/dist/src/extensions/(backend)/api/_lib/route.server.cjs +93 -0
- package/dist/src/extensions/(backend)/api/_lib/route.server.cjs.map +1 -0
- package/dist/src/extensions/(backend)/api/_lib/route.server.mjs +92 -0
- package/dist/src/extensions/(backend)/api/_lib/route.server.mjs.map +1 -0
- package/dist/src/extensions/(backend)/api/route.server.cjs +7 -0
- package/dist/src/extensions/(backend)/api/route.server.cjs.map +1 -0
- package/dist/src/extensions/(backend)/api/route.server.mjs +8 -0
- package/dist/src/extensions/(backend)/api/route.server.mjs.map +1 -0
- package/dist/src/extensions/(backend)/channel/_lib/git-worktrees.server.cjs +195 -0
- package/dist/src/extensions/(backend)/channel/_lib/git-worktrees.server.cjs.map +1 -0
- package/dist/src/extensions/(backend)/channel/_lib/git-worktrees.server.mjs +194 -0
- package/dist/src/extensions/(backend)/channel/_lib/git-worktrees.server.mjs.map +1 -0
- package/dist/src/extensions/(backend)/channel/git-worktrees.server.cjs +7 -0
- package/dist/src/extensions/(backend)/channel/git-worktrees.server.cjs.map +1 -0
- package/dist/src/extensions/(backend)/channel/git-worktrees.server.mjs +8 -0
- package/dist/src/extensions/(backend)/channel/git-worktrees.server.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/root.cli.cjs +7 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/root.cli.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/root.cli.mjs +8 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/root.cli.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/root.server.cjs +71 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/root.server.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/root.server.mjs +70 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/root.server.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/command/_lib/git.cli.cjs +17 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/command/_lib/git.cli.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/command/_lib/git.cli.mjs +16 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/command/_lib/git.cli.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/command/git.cli.cjs +7 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/command/git.cli.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/command/git.cli.mjs +8 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/command/git.cli.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompi-use-git.cli.cjs +15 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompi-use-git.cli.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompi-use-git.cli.mjs +15 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompi-use-git.cli.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGit.server.cjs +6 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGit.server.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGit.server.mjs +6 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGit.server.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGitReadme.server.cjs +6 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGitReadme.server.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGitReadme.server.mjs +6 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiGitReadme.server.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiUseGit.server.cjs +6 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiUseGit.server.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiUseGit.server.mjs +6 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/_lib/doompiUseGit.server.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompi-use-git.cli.cjs +7 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompi-use-git.cli.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompi-use-git.cli.mjs +8 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompi-use-git.cli.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiGit.server.cjs +7 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiGit.server.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiGit.server.mjs +8 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiGit.server.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiGitReadme.server.cjs +7 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiGitReadme.server.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiGitReadme.server.mjs +8 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiGitReadme.server.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiUseGit.server.cjs +7 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiUseGit.server.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiUseGit.server.mjs +8 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiUseGit.server.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/root.cli.cjs +7 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/root.cli.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/root.cli.mjs +8 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/root.cli.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/root.server.cjs +7 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/root.server.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/root.server.mjs +8 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/root.server.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/_lib/runWorktree.cli.cjs +38 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/_lib/runWorktree.cli.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/_lib/runWorktree.cli.mjs +36 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/_lib/runWorktree.cli.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/runWorktree.cli.cjs +7 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/runWorktree.cli.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/runWorktree.cli.mjs +8 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/runWorktree.cli.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/runWorktree.server.cjs +6 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/runWorktree.server.cjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/runWorktree.server.mjs +7 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/runWorktree.server.mjs.map +1 -0
- package/dist/src/schemas/apiContracts.cjs +138 -0
- package/dist/src/schemas/apiContracts.cjs.map +1 -0
- package/dist/{schemas → src/schemas}/apiContracts.d.cts.map +1 -1
- package/dist/{schemas → src/schemas}/apiContracts.d.mts.map +1 -1
- package/dist/src/schemas/apiContracts.mjs +135 -0
- package/dist/src/schemas/apiContracts.mjs.map +1 -0
- package/dist/src/schemas/runWorktreeTool.cjs +152 -0
- package/dist/src/schemas/runWorktreeTool.cjs.map +1 -0
- package/dist/src/schemas/runWorktreeTool.mjs +150 -0
- package/dist/src/schemas/runWorktreeTool.mjs.map +1 -0
- package/dist/src/services/atomicJson/index.cjs +42 -0
- package/dist/src/services/atomicJson/index.cjs.map +1 -0
- package/dist/src/services/atomicJson/index.mjs +38 -0
- package/dist/src/services/atomicJson/index.mjs.map +1 -0
- package/dist/src/services/compositionMirror/index.cjs +119 -0
- package/dist/src/services/compositionMirror/index.cjs.map +1 -0
- package/dist/src/services/compositionMirror/index.mjs +116 -0
- package/dist/src/services/compositionMirror/index.mjs.map +1 -0
- package/dist/src/services/errors/index.cjs +29 -0
- package/dist/src/services/errors/index.cjs.map +1 -0
- package/dist/src/services/errors/index.mjs +27 -0
- package/dist/src/services/errors/index.mjs.map +1 -0
- package/dist/src/services/extensionService/index.cjs +13 -0
- package/dist/src/services/extensionService/index.cjs.map +1 -0
- package/dist/src/services/extensionService/index.d.cts.map +1 -0
- package/dist/src/services/extensionService/index.d.mts.map +1 -0
- package/dist/src/services/extensionService/index.mjs +13 -0
- package/dist/src/services/extensionService/index.mjs.map +1 -0
- package/dist/src/services/gitCli/index.cjs +144 -0
- package/dist/src/services/gitCli/index.cjs.map +1 -0
- package/dist/src/services/gitCli/index.mjs +142 -0
- package/dist/src/services/gitCli/index.mjs.map +1 -0
- package/dist/src/services/gitDependencies/index.cjs +14 -0
- package/dist/src/services/gitDependencies/index.cjs.map +1 -0
- package/dist/src/services/gitDependencies/index.d.cts.map +1 -0
- package/dist/src/services/gitDependencies/index.d.mts.map +1 -0
- package/dist/src/services/gitDependencies/index.mjs +14 -0
- package/dist/src/services/gitDependencies/index.mjs.map +1 -0
- package/dist/src/services/paths/index.cjs +35 -0
- package/dist/src/services/paths/index.cjs.map +1 -0
- package/dist/src/services/paths/index.mjs +30 -0
- package/dist/src/services/paths/index.mjs.map +1 -0
- package/dist/src/services/repositoryIdentity/index.cjs +71 -0
- package/dist/src/services/repositoryIdentity/index.cjs.map +1 -0
- package/dist/src/services/repositoryIdentity/index.mjs +65 -0
- package/dist/src/services/repositoryIdentity/index.mjs.map +1 -0
- package/dist/src/services/runWorktree/index.cjs +145 -0
- package/dist/src/services/runWorktree/index.cjs.map +1 -0
- package/dist/src/services/runWorktree/index.mjs +142 -0
- package/dist/src/services/runWorktree/index.mjs.map +1 -0
- package/dist/src/services/worktreeEvents/index.cjs +64 -0
- package/dist/src/services/worktreeEvents/index.cjs.map +1 -0
- package/dist/src/services/worktreeEvents/index.d.cts.map +1 -0
- package/dist/src/services/worktreeEvents/index.d.mts.map +1 -0
- package/dist/src/services/worktreeEvents/index.mjs +60 -0
- package/dist/src/services/worktreeEvents/index.mjs.map +1 -0
- package/dist/src/services/worktreeNaming/index.cjs +99 -0
- package/dist/src/services/worktreeNaming/index.cjs.map +1 -0
- package/dist/src/services/worktreeNaming/index.d.cts.map +1 -0
- package/dist/src/services/worktreeNaming/index.d.mts.map +1 -0
- package/dist/src/services/worktreeNaming/index.mjs +94 -0
- package/dist/src/services/worktreeNaming/index.mjs.map +1 -0
- package/dist/src/services/worktreeOperations/index.cjs +263 -0
- package/dist/src/services/worktreeOperations/index.cjs.map +1 -0
- package/dist/src/services/worktreeOperations/index.d.cts.map +1 -0
- package/dist/src/services/worktreeOperations/index.d.mts.map +1 -0
- package/dist/src/services/worktreeOperations/index.mjs +261 -0
- package/dist/src/services/worktreeOperations/index.mjs.map +1 -0
- package/dist/src/services/worktreeRegistry/index.cjs +38 -0
- package/dist/src/services/worktreeRegistry/index.cjs.map +1 -0
- package/dist/src/services/worktreeRegistry/index.mjs +38 -0
- package/dist/src/services/worktreeRegistry/index.mjs.map +1 -0
- package/dist/src/types/extension.d.cts.map +1 -0
- package/dist/src/types/extension.d.mts.map +1 -0
- package/dist/src/types/webWorktrees.cjs +20 -0
- package/dist/src/types/webWorktrees.cjs.map +1 -0
- package/dist/src/types/webWorktrees.mjs +20 -0
- package/dist/src/types/webWorktrees.mjs.map +1 -0
- package/dist/src/types/worktreeRegistry.d.cts.map +1 -0
- package/dist/src/types/worktreeRegistry.d.mts.map +1 -0
- package/package.json +24 -19
- package/dist/constants/git.cjs +0 -2
- package/dist/constants/git.cjs.map +0 -1
- package/dist/constants/git.mjs +0 -2
- package/dist/constants/git.mjs.map +0 -1
- package/dist/controllers/gitCommand.cjs +0 -2
- package/dist/controllers/gitCommand.cjs.map +0 -1
- package/dist/controllers/gitCommand.mjs +0 -2
- package/dist/controllers/gitCommand.mjs.map +0 -1
- package/dist/controllers/gitSession.cjs +0 -2
- package/dist/controllers/gitSession.cjs.map +0 -1
- package/dist/controllers/gitSession.mjs +0 -2
- package/dist/controllers/gitSession.mjs.map +0 -1
- package/dist/controllers/hubApi.cjs +0 -2
- package/dist/controllers/hubApi.cjs.map +0 -1
- package/dist/controllers/hubApi.mjs +0 -2
- package/dist/controllers/hubApi.mjs.map +0 -1
- package/dist/controllers/worktreesChannel.cjs +0 -2
- package/dist/controllers/worktreesChannel.cjs.map +0 -1
- package/dist/controllers/worktreesChannel.mjs +0 -2
- package/dist/controllers/worktreesChannel.mjs.map +0 -1
- package/dist/schemas/apiContracts.cjs +0 -2
- package/dist/schemas/apiContracts.cjs.map +0 -1
- package/dist/schemas/apiContracts.mjs +0 -2
- package/dist/schemas/apiContracts.mjs.map +0 -1
- package/dist/schemas/runWorktreeTool.cjs +0 -2
- package/dist/schemas/runWorktreeTool.cjs.map +0 -1
- package/dist/schemas/runWorktreeTool.mjs +0 -2
- package/dist/schemas/runWorktreeTool.mjs.map +0 -1
- package/dist/services/atomicJson/index.cjs +0 -2
- package/dist/services/atomicJson/index.cjs.map +0 -1
- package/dist/services/atomicJson/index.mjs +0 -2
- package/dist/services/atomicJson/index.mjs.map +0 -1
- package/dist/services/compositionMirror/index.cjs +0 -2
- package/dist/services/compositionMirror/index.cjs.map +0 -1
- package/dist/services/compositionMirror/index.mjs +0 -2
- package/dist/services/compositionMirror/index.mjs.map +0 -1
- package/dist/services/errors/index.cjs +0 -2
- package/dist/services/errors/index.cjs.map +0 -1
- package/dist/services/errors/index.mjs +0 -2
- package/dist/services/errors/index.mjs.map +0 -1
- package/dist/services/extensionService/index.cjs +0 -2
- package/dist/services/extensionService/index.cjs.map +0 -1
- package/dist/services/extensionService/index.d.cts.map +0 -1
- package/dist/services/extensionService/index.d.mts.map +0 -1
- package/dist/services/extensionService/index.mjs +0 -2
- package/dist/services/extensionService/index.mjs.map +0 -1
- package/dist/services/gitCli/index.cjs +0 -4
- package/dist/services/gitCli/index.cjs.map +0 -1
- package/dist/services/gitCli/index.mjs +0 -4
- package/dist/services/gitCli/index.mjs.map +0 -1
- package/dist/services/gitDependencies/index.cjs +0 -2
- package/dist/services/gitDependencies/index.cjs.map +0 -1
- package/dist/services/gitDependencies/index.d.cts.map +0 -1
- package/dist/services/gitDependencies/index.d.mts.map +0 -1
- package/dist/services/gitDependencies/index.mjs +0 -2
- package/dist/services/gitDependencies/index.mjs.map +0 -1
- package/dist/services/paths/index.cjs +0 -2
- package/dist/services/paths/index.cjs.map +0 -1
- package/dist/services/paths/index.mjs +0 -2
- package/dist/services/paths/index.mjs.map +0 -1
- package/dist/services/repositoryIdentity/index.cjs +0 -2
- package/dist/services/repositoryIdentity/index.cjs.map +0 -1
- package/dist/services/repositoryIdentity/index.mjs +0 -2
- package/dist/services/repositoryIdentity/index.mjs.map +0 -1
- package/dist/services/runWorktree/index.cjs +0 -15
- package/dist/services/runWorktree/index.cjs.map +0 -1
- package/dist/services/runWorktree/index.mjs +0 -15
- package/dist/services/runWorktree/index.mjs.map +0 -1
- package/dist/services/worktreeEvents/index.cjs +0 -2
- package/dist/services/worktreeEvents/index.cjs.map +0 -1
- package/dist/services/worktreeEvents/index.d.cts.map +0 -1
- package/dist/services/worktreeEvents/index.d.mts.map +0 -1
- package/dist/services/worktreeEvents/index.mjs +0 -2
- package/dist/services/worktreeEvents/index.mjs.map +0 -1
- package/dist/services/worktreeNaming/index.cjs +0 -2
- package/dist/services/worktreeNaming/index.cjs.map +0 -1
- package/dist/services/worktreeNaming/index.d.cts.map +0 -1
- package/dist/services/worktreeNaming/index.d.mts.map +0 -1
- package/dist/services/worktreeNaming/index.mjs +0 -2
- package/dist/services/worktreeNaming/index.mjs.map +0 -1
- package/dist/services/worktreeOperations/index.cjs +0 -2
- package/dist/services/worktreeOperations/index.cjs.map +0 -1
- package/dist/services/worktreeOperations/index.d.cts.map +0 -1
- package/dist/services/worktreeOperations/index.d.mts.map +0 -1
- package/dist/services/worktreeOperations/index.mjs +0 -2
- package/dist/services/worktreeOperations/index.mjs.map +0 -1
- package/dist/services/worktreeRegistry/index.cjs +0 -2
- package/dist/services/worktreeRegistry/index.cjs.map +0 -1
- package/dist/services/worktreeRegistry/index.mjs +0 -2
- package/dist/services/worktreeRegistry/index.mjs.map +0 -1
- package/dist/tools/runWorktree.cjs +0 -2
- package/dist/tools/runWorktree.cjs.map +0 -1
- package/dist/tools/runWorktree.mjs +0 -2
- package/dist/tools/runWorktree.mjs.map +0 -1
- package/dist/types/extension.d.cts.map +0 -1
- package/dist/types/extension.d.mts.map +0 -1
- package/dist/types/webWorktrees.cjs +0 -2
- package/dist/types/webWorktrees.cjs.map +0 -1
- package/dist/types/webWorktrees.mjs +0 -2
- package/dist/types/webWorktrees.mjs.map +0 -1
- package/dist/types/worktreeRegistry.d.cts.map +0 -1
- package/dist/types/worktreeRegistry.d.mts.map +0 -1
- package/src/extensions/web.ts +0 -33
- package/src/types/webWorktrees.ts +0 -55
- package/src/types/worktreeRegistry.ts +0 -78
- package/src/web/components/RunWorktreeToolMessage.tsx +0 -45
- package/src/web/components/WorktreesActivitySection.tsx +0 -80
- package/src/web/components/WorktreesPanel.tsx +0 -175
- package/src/web/components/toolRenderers.ts +0 -8
- package/src/web/stores/worktreesActivityStore.ts +0 -125
- package/src/web/tsconfig.json +0 -22
- /package/dist/{schemas → src/schemas}/apiContracts.d.cts +0 -0
- /package/dist/{schemas → src/schemas}/apiContracts.d.mts +0 -0
- /package/dist/{services → src/services}/extensionService/index.d.cts +0 -0
- /package/dist/{services → src/services}/extensionService/index.d.mts +0 -0
- /package/dist/{services → src/services}/gitDependencies/index.d.cts +0 -0
- /package/dist/{services → src/services}/gitDependencies/index.d.mts +0 -0
- /package/dist/{services → src/services}/worktreeEvents/index.d.cts +0 -0
- /package/dist/{services → src/services}/worktreeEvents/index.d.mts +0 -0
- /package/dist/{services → src/services}/worktreeNaming/index.d.cts +0 -0
- /package/dist/{services → src/services}/worktreeNaming/index.d.mts +0 -0
- /package/dist/{services → src/services}/worktreeOperations/index.d.cts +0 -0
- /package/dist/{services → src/services}/worktreeOperations/index.d.mts +0 -0
- /package/dist/{types → src/types}/extension.d.cts +0 -0
- /package/dist/{types → src/types}/extension.d.mts +0 -0
- /package/dist/{types → src/types}/worktreeRegistry.d.cts +0 -0
- /package/dist/{types → src/types}/worktreeRegistry.d.mts +0 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
//#region src/services/gitCli/index.ts
|
|
4
|
+
/**
|
|
5
|
+
* Git, as this package needs it.
|
|
6
|
+
*
|
|
7
|
+
* The timeouts are not uniform because the operations are not comparable. A
|
|
8
|
+
* read answers in milliseconds; `worktree add` copies an entire checkout and
|
|
9
|
+
* `worktree remove` deletes one, both bounded by the filesystem rather than by
|
|
10
|
+
* git, and both minutes rather than seconds on a large repository or on
|
|
11
|
+
* Windows. A single timeout would either fail honest work or hang on a wedged
|
|
12
|
+
* one.
|
|
13
|
+
*/
|
|
14
|
+
const READ_TIMEOUT_MS = 3e4;
|
|
15
|
+
const ADD_TIMEOUT_MS = 3e5;
|
|
16
|
+
const REMOVE_TIMEOUT_MS = 3e5;
|
|
17
|
+
const PRUNE_TIMEOUT_MS = 15e3;
|
|
18
|
+
const MAX_OUTPUT_BYTES = 1e6;
|
|
19
|
+
/**
|
|
20
|
+
* Runs git and reports the outcome without ever throwing on a non-zero exit.
|
|
21
|
+
*
|
|
22
|
+
* LC_ALL is pinned because two callers below decide what to do by matching
|
|
23
|
+
* git's own wording, and a translated message would silently turn a recognised
|
|
24
|
+
* condition into an unrecognised failure.
|
|
25
|
+
*/
|
|
26
|
+
function git(cwd, args, timeout) {
|
|
27
|
+
return new Promise((resolve) => {
|
|
28
|
+
execFile("git", [...args], {
|
|
29
|
+
cwd,
|
|
30
|
+
timeout,
|
|
31
|
+
maxBuffer: MAX_OUTPUT_BYTES,
|
|
32
|
+
env: {
|
|
33
|
+
...process.env,
|
|
34
|
+
LC_ALL: "C"
|
|
35
|
+
}
|
|
36
|
+
}, (error, stdout, stderr) => {
|
|
37
|
+
resolve({
|
|
38
|
+
code: error && typeof error.code === "number" ? error.code : error ? 1 : 0,
|
|
39
|
+
stdout: String(stdout),
|
|
40
|
+
stderr: String(stderr)
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The message a failed git call is allowed to surface.
|
|
47
|
+
*
|
|
48
|
+
* Raw stderr never travels: it can carry a remote URL with a token in it, and
|
|
49
|
+
* this text ends up in a tool result the model reads and may repeat.
|
|
50
|
+
*/
|
|
51
|
+
function failure(operation, result) {
|
|
52
|
+
return /* @__PURE__ */ new Error(`git ${operation} failed (exit ${String(result.code)}, ${String(result.stderr.length)} bytes of stderr)`);
|
|
53
|
+
}
|
|
54
|
+
/** Git's own words for "that worktree is not there any more". */
|
|
55
|
+
function missingWorktree(stderr) {
|
|
56
|
+
const normalized = stderr.toLowerCase();
|
|
57
|
+
return normalized.includes("is not a working tree") || normalized.includes("cannot remove working tree");
|
|
58
|
+
}
|
|
59
|
+
function createWorktreeGit() {
|
|
60
|
+
const prune = async (repositoryRoot) => {
|
|
61
|
+
await git(repositoryRoot, ["worktree", "prune"], PRUNE_TIMEOUT_MS);
|
|
62
|
+
};
|
|
63
|
+
return {
|
|
64
|
+
async addWorktree({ repositoryRoot, path, branch, baseRef }) {
|
|
65
|
+
const result = await git(repositoryRoot, [
|
|
66
|
+
"worktree",
|
|
67
|
+
"add",
|
|
68
|
+
"-b",
|
|
69
|
+
branch,
|
|
70
|
+
path,
|
|
71
|
+
baseRef
|
|
72
|
+
], ADD_TIMEOUT_MS);
|
|
73
|
+
if (result.code !== 0) throw failure("worktree add", result);
|
|
74
|
+
},
|
|
75
|
+
async removeWorktree({ repositoryRoot, path, force }) {
|
|
76
|
+
const result = await git(repositoryRoot, [
|
|
77
|
+
"worktree",
|
|
78
|
+
"remove",
|
|
79
|
+
...force ? ["--force"] : [],
|
|
80
|
+
path
|
|
81
|
+
], REMOVE_TIMEOUT_MS);
|
|
82
|
+
if (result.code === 0) return;
|
|
83
|
+
if (missingWorktree(result.stderr) && !fs.existsSync(path)) {
|
|
84
|
+
await prune(repositoryRoot);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
throw failure("worktree remove", result);
|
|
88
|
+
},
|
|
89
|
+
async deleteBranch({ repositoryRoot, branch }) {
|
|
90
|
+
return (await git(repositoryRoot, [
|
|
91
|
+
"branch",
|
|
92
|
+
"-d",
|
|
93
|
+
branch
|
|
94
|
+
], READ_TIMEOUT_MS)).code === 0;
|
|
95
|
+
},
|
|
96
|
+
pruneWorktrees: prune,
|
|
97
|
+
async listWorktreePaths(repositoryRoot) {
|
|
98
|
+
const result = await git(repositoryRoot, [
|
|
99
|
+
"worktree",
|
|
100
|
+
"list",
|
|
101
|
+
"--porcelain"
|
|
102
|
+
], READ_TIMEOUT_MS);
|
|
103
|
+
if (result.code !== 0) return [];
|
|
104
|
+
return result.stdout.split("\n").filter((line) => line.startsWith("worktree ")).map((line) => line.slice(9).trim()).filter((line) => line !== "");
|
|
105
|
+
},
|
|
106
|
+
async dirtyFiles(path) {
|
|
107
|
+
const result = await git(path, ["status", "--porcelain"], READ_TIMEOUT_MS);
|
|
108
|
+
if (result.code !== 0) return [];
|
|
109
|
+
return result.stdout.split("\n").map((line) => line.slice(3).trim()).filter((line) => line !== "");
|
|
110
|
+
},
|
|
111
|
+
async repositoryRoot(cwd) {
|
|
112
|
+
const result = await git(cwd, ["rev-parse", "--show-toplevel"], READ_TIMEOUT_MS);
|
|
113
|
+
if (result.code !== 0) return void 0;
|
|
114
|
+
const root = result.stdout.trim();
|
|
115
|
+
return root === "" ? void 0 : root;
|
|
116
|
+
},
|
|
117
|
+
async currentBranch(cwd) {
|
|
118
|
+
const result = await git(cwd, [
|
|
119
|
+
"rev-parse",
|
|
120
|
+
"--abbrev-ref",
|
|
121
|
+
"HEAD"
|
|
122
|
+
], READ_TIMEOUT_MS);
|
|
123
|
+
if (result.code !== 0) return void 0;
|
|
124
|
+
const branch = result.stdout.trim();
|
|
125
|
+
return branch === "" ? void 0 : branch;
|
|
126
|
+
},
|
|
127
|
+
async mergeBranch({ repositoryRoot, branch, message }) {
|
|
128
|
+
const result = await git(repositoryRoot, [
|
|
129
|
+
"merge",
|
|
130
|
+
"--no-ff",
|
|
131
|
+
...message === void 0 ? [] : ["-m", message],
|
|
132
|
+
branch
|
|
133
|
+
], READ_TIMEOUT_MS);
|
|
134
|
+
if (result.code === 0) return;
|
|
135
|
+
throw failure("merge", result);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
//#endregion
|
|
140
|
+
export { createWorktreeGit };
|
|
141
|
+
|
|
142
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/services/gitCli/index.ts"],"sourcesContent":["import { execFile } from 'node:child_process';\nimport fs from 'node:fs';\n\nimport type { WorktreeGit } from '../../types/worktreeRegistry';\n\n/**\n * Git, as this package needs it.\n *\n * The timeouts are not uniform because the operations are not comparable. A\n * read answers in milliseconds; `worktree add` copies an entire checkout and\n * `worktree remove` deletes one, both bounded by the filesystem rather than by\n * git, and both minutes rather than seconds on a large repository or on\n * Windows. A single timeout would either fail honest work or hang on a wedged\n * one.\n */\nconst READ_TIMEOUT_MS = 30_000;\nconst ADD_TIMEOUT_MS = 300_000;\nconst REMOVE_TIMEOUT_MS = 300_000;\nconst PRUNE_TIMEOUT_MS = 15_000;\nconst MAX_OUTPUT_BYTES = 1_000_000;\n\ninterface GitResult {\n code: number;\n stdout: string;\n stderr: string;\n}\n\n/**\n * Runs git and reports the outcome without ever throwing on a non-zero exit.\n *\n * LC_ALL is pinned because two callers below decide what to do by matching\n * git's own wording, and a translated message would silently turn a recognised\n * condition into an unrecognised failure.\n */\nfunction git(cwd: string, args: readonly string[], timeout: number): Promise<GitResult> {\n return new Promise((resolve) => {\n execFile(\n 'git',\n [...args],\n { cwd, timeout, maxBuffer: MAX_OUTPUT_BYTES, env: { ...process.env, LC_ALL: 'C' } },\n (error, stdout, stderr) => {\n const code = error && typeof error.code === 'number' ? error.code : error ? 1 : 0;\n resolve({ code, stdout: String(stdout), stderr: String(stderr) });\n },\n );\n });\n}\n\n/**\n * The message a failed git call is allowed to surface.\n *\n * Raw stderr never travels: it can carry a remote URL with a token in it, and\n * this text ends up in a tool result the model reads and may repeat.\n */\nfunction failure(operation: string, result: GitResult): Error {\n return new Error(\n `git ${operation} failed (exit ${String(result.code)}, ${String(result.stderr.length)} bytes of stderr)`,\n );\n}\n\n/** Git's own words for \"that worktree is not there any more\". */\nfunction missingWorktree(stderr: string): boolean {\n const normalized = stderr.toLowerCase();\n return normalized.includes('is not a working tree') || normalized.includes('cannot remove working tree');\n}\n\nexport function createWorktreeGit(): WorktreeGit {\n const prune = async (repositoryRoot: string): Promise<void> => {\n await git(repositoryRoot, ['worktree', 'prune'], PRUNE_TIMEOUT_MS);\n };\n\n return {\n async addWorktree({ repositoryRoot, path, branch, baseRef }) {\n const result = await git(repositoryRoot, ['worktree', 'add', '-b', branch, path, baseRef], ADD_TIMEOUT_MS);\n if (result.code !== 0) throw failure('worktree add', result);\n },\n\n async removeWorktree({ repositoryRoot, path, force }) {\n const args = ['worktree', 'remove', ...(force ? ['--force'] : []), path];\n const result = await git(repositoryRoot, args, REMOVE_TIMEOUT_MS);\n if (result.code === 0) return;\n // A directory deleted behind git's back leaves an administrative entry\n // that makes a later `worktree add` at the same path refuse. Treating\n // \"already gone\" as success and pruning is what keeps that path reusable,\n // and it makes remove idempotent for a caller retrying after a crash.\n if (missingWorktree(result.stderr) && !fs.existsSync(path)) {\n await prune(repositoryRoot);\n return;\n }\n throw failure('worktree remove', result);\n },\n\n async deleteBranch({ repositoryRoot, branch }) {\n // -d, never -D: git refuses a branch that still holds unmerged commits,\n // and that refusal is the whole safety property. A rollback that could\n // throw away work someone committed in the worktree is worse than a\n // branch left behind.\n const result = await git(repositoryRoot, ['branch', '-d', branch], READ_TIMEOUT_MS);\n return result.code === 0;\n },\n pruneWorktrees: prune,\n\n async listWorktreePaths(repositoryRoot) {\n const result = await git(repositoryRoot, ['worktree', 'list', '--porcelain'], READ_TIMEOUT_MS);\n if (result.code !== 0) return [];\n return result.stdout\n .split('\\n')\n .filter((line) => line.startsWith('worktree '))\n .map((line) => line.slice('worktree '.length).trim())\n .filter((line) => line !== '');\n },\n\n async dirtyFiles(path) {\n const result = await git(path, ['status', '--porcelain'], READ_TIMEOUT_MS);\n if (result.code !== 0) return [];\n return result.stdout\n .split('\\n')\n .map((line) => line.slice(3).trim())\n .filter((line) => line !== '');\n },\n\n async repositoryRoot(cwd) {\n const result = await git(cwd, ['rev-parse', '--show-toplevel'], READ_TIMEOUT_MS);\n if (result.code !== 0) return undefined;\n const root = result.stdout.trim();\n return root === '' ? undefined : root;\n },\n\n async currentBranch(cwd) {\n const result = await git(cwd, ['rev-parse', '--abbrev-ref', 'HEAD'], READ_TIMEOUT_MS);\n if (result.code !== 0) return undefined;\n const branch = result.stdout.trim();\n return branch === '' ? undefined : branch;\n },\n\n async mergeBranch({ repositoryRoot, branch, message }) {\n // --no-ff so the worktree's work stays identifiable as a unit after the\n // fact. A fast-forward would erase the fact that it was ever separate,\n // which is the one thing worth keeping about a worktree.\n const args = ['merge', '--no-ff', ...(message === undefined ? [] : ['-m', message]), branch];\n const result = await git(repositoryRoot, args, READ_TIMEOUT_MS);\n if (result.code === 0) return;\n // A conflicted merge leaves the parent mid-merge, which is a state the\n // person has to resolve; aborting for them would throw away the conflict\n // markers they need to see.\n throw failure('merge', result);\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const require_index = require("../extensionService/index.cjs");
|
|
2
|
+
const require_index$1 = require("../gitCli/index.cjs");
|
|
3
|
+
const require_index$2 = require("../worktreeOperations/index.cjs");
|
|
4
|
+
//#region src/services/gitDependencies/index.ts
|
|
5
|
+
function createGitDependencies(overrides = {}) {
|
|
6
|
+
return {
|
|
7
|
+
service: overrides.service ?? new require_index.DefaultGitExtensionService(),
|
|
8
|
+
operations: overrides.operations ?? require_index$2.createWorktreeOperations({ git: require_index$1.createWorktreeGit() })
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
exports.createGitDependencies = createGitDependencies;
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["DefaultGitExtensionService","createWorktreeOperations","createWorktreeGit"],"sources":["../../../../src/services/gitDependencies/index.ts"],"sourcesContent":["import type { GitExtensionDependencies } from '../../types/extension';\nimport { DefaultGitExtensionService } from '../extensionService';\n// @scaffold-generated\nimport { createWorktreeGit } from '../gitCli';\nimport { createWorktreeOperations } from '../worktreeOperations';\n\nexport function createGitDependencies(overrides: Partial<GitExtensionDependencies> = {}): GitExtensionDependencies {\n return {\n service: overrides.service ?? new DefaultGitExtensionService(),\n operations: overrides.operations ?? createWorktreeOperations({ git: createWorktreeGit() }),\n };\n}\n"],"mappings":";;;;AAMA,SAAgB,sBAAsB,YAA+C,CAAC,GAA6B;CACjH,OAAO;EACL,SAAS,UAAU,WAAW,IAAIA,cAAAA,2BAA2B;EAC7D,YAAY,UAAU,cAAcC,gBAAAA,yBAAyB,EAAE,KAAKC,gBAAAA,kBAAkB,EAAE,CAAC;CAC3F;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../../src/services/gitDependencies/index.ts"],"mappings":";;wBAMgB,sBAAsB,YAAW,QAAQ,4BAAiC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../../../src/services/gitDependencies/index.ts"],"mappings":";;wBAMgB,sBAAsB,YAAW,QAAQ,4BAAiC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DefaultGitExtensionService } from "../extensionService/index.mjs";
|
|
2
|
+
import { createWorktreeGit } from "../gitCli/index.mjs";
|
|
3
|
+
import { createWorktreeOperations } from "../worktreeOperations/index.mjs";
|
|
4
|
+
//#region src/services/gitDependencies/index.ts
|
|
5
|
+
function createGitDependencies(overrides = {}) {
|
|
6
|
+
return {
|
|
7
|
+
service: overrides.service ?? new DefaultGitExtensionService(),
|
|
8
|
+
operations: overrides.operations ?? createWorktreeOperations({ git: createWorktreeGit() })
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { createGitDependencies };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/services/gitDependencies/index.ts"],"sourcesContent":["import type { GitExtensionDependencies } from '../../types/extension';\nimport { DefaultGitExtensionService } from '../extensionService';\n// @scaffold-generated\nimport { createWorktreeGit } from '../gitCli';\nimport { createWorktreeOperations } from '../worktreeOperations';\n\nexport function createGitDependencies(overrides: Partial<GitExtensionDependencies> = {}): GitExtensionDependencies {\n return {\n service: overrides.service ?? new DefaultGitExtensionService(),\n operations: overrides.operations ?? createWorktreeOperations({ git: createWorktreeGit() }),\n };\n}\n"],"mappings":";;;;AAMA,SAAgB,sBAAsB,YAA+C,CAAC,GAA6B;CACjH,OAAO;EACL,SAAS,UAAU,WAAW,IAAI,2BAA2B;EAC7D,YAAY,UAAU,cAAc,yBAAyB,EAAE,KAAK,kBAAkB,EAAE,CAAC;CAC3F;AACF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
const require_index = require("../repositoryIdentity/index.cjs");
|
|
3
|
+
let node_path = require("node:path");
|
|
4
|
+
node_path = require_runtime.__toESM(node_path, 1);
|
|
5
|
+
let node_os = require("node:os");
|
|
6
|
+
node_os = require_runtime.__toESM(node_os, 1);
|
|
7
|
+
require("@agimon-ai/doompi-core/web");
|
|
8
|
+
//#region src/services/paths/index.ts
|
|
9
|
+
/**
|
|
10
|
+
* Where this package keeps its own state.
|
|
11
|
+
*
|
|
12
|
+
* Outside the repository on purpose. A worktree directory inside the checkout
|
|
13
|
+
* would be found by every glob the repository's own tooling runs, and would
|
|
14
|
+
* resolve workspace imports against the parent checkout rather than the
|
|
15
|
+
* worktree, so a session there would build the wrong source while appearing to
|
|
16
|
+
* work.
|
|
17
|
+
*/
|
|
18
|
+
function doomGitRoot(homeDir = node_os.default.homedir()) {
|
|
19
|
+
return node_path.default.join(homeDir, ".pi", ".doom", "git");
|
|
20
|
+
}
|
|
21
|
+
/** The directory every worktree for every repository is created under. */
|
|
22
|
+
function worktreesRoot(homeDir = node_os.default.homedir()) {
|
|
23
|
+
return node_path.default.join(doomGitRoot(homeDir), "worktrees");
|
|
24
|
+
}
|
|
25
|
+
/** One registry file per repository, keyed by the shared git directory. */
|
|
26
|
+
function registryFile(repositoryRoot, homeDir = node_os.default.homedir()) {
|
|
27
|
+
const key = `${require_index.repositoryLabel(repositoryRoot)}--${require_index.repositoryId(repositoryRoot)}`;
|
|
28
|
+
return node_path.default.join(doomGitRoot(homeDir), "registry", key, "worktrees.json");
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
exports.doomGitRoot = doomGitRoot;
|
|
32
|
+
exports.registryFile = registryFile;
|
|
33
|
+
exports.worktreesRoot = worktreesRoot;
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["os","path","repositoryLabel","repositoryId"],"sources":["../../../../src/services/paths/index.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\n\nimport { REGISTRY_DIR_ENV, resolveRegistryDir } from '@agimon-ai/doompi-core/web';\n\nimport { repositoryId, repositoryLabel } from '../repositoryIdentity';\n\nconst REGISTRY_DIR_FLAG = '--registry-dir';\n\n/**\n * Where this package keeps its own state.\n *\n * Outside the repository on purpose. A worktree directory inside the checkout\n * would be found by every glob the repository's own tooling runs, and would\n * resolve workspace imports against the parent checkout rather than the\n * worktree, so a session there would build the wrong source while appearing to\n * work.\n */\nexport function doomGitRoot(homeDir: string = os.homedir()): string {\n return path.join(homeDir, '.pi', '.doom', 'git');\n}\n\n/** The directory every worktree for every repository is created under. */\nexport function worktreesRoot(homeDir: string = os.homedir()): string {\n return path.join(doomGitRoot(homeDir), 'worktrees');\n}\n\n/** One registry file per repository, keyed by the shared git directory. */\n\nexport function registryFile(repositoryRoot: string, homeDir: string = os.homedir()): string {\n const key = `${repositoryLabel(repositoryRoot)}--${repositoryId(repositoryRoot)}`;\n return path.join(doomGitRoot(homeDir), 'registry', key, 'worktrees.json');\n}\n\n/**\n * The session registry directory this process's hub is watching.\n *\n * A spawned session only appears in the rail if it registers in the same\n * directory the hub watches, and the hub passes that directory to its children\n * as `--registry-dir` while also inheriting the env var. Recovering it from\n * this process's own argv and env, in the same precedence the hub and the\n * session server use, is what makes a worktree session visible rather than\n * silently invisible.\n */\nexport function hubRegistryDir(\n argv: readonly string[] = process.argv,\n env: NodeJS.ProcessEnv = process.env,\n homeDir: string = os.homedir(),\n): string {\n const index = argv.indexOf(REGISTRY_DIR_FLAG);\n const flagValue = index >= 0 ? argv[index + 1] : undefined;\n return resolveRegistryDir({\n ...(flagValue === undefined ? {} : { flagValue }),\n ...(env[REGISTRY_DIR_ENV] === undefined ? {} : { envValue: env[REGISTRY_DIR_ENV] }),\n homeDir,\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAkBA,SAAgB,YAAY,UAAkBA,QAAAA,QAAG,QAAQ,GAAW;CAClE,OAAOC,UAAAA,QAAK,KAAK,SAAS,OAAO,SAAS,KAAK;AACjD;;AAGA,SAAgB,cAAc,UAAkBD,QAAAA,QAAG,QAAQ,GAAW;CACpE,OAAOC,UAAAA,QAAK,KAAK,YAAY,OAAO,GAAG,WAAW;AACpD;;AAIA,SAAgB,aAAa,gBAAwB,UAAkBD,QAAAA,QAAG,QAAQ,GAAW;CAC3F,MAAM,MAAM,GAAGE,cAAAA,gBAAgB,cAAc,EAAE,IAAIC,cAAAA,aAAa,cAAc;CAC9E,OAAOF,UAAAA,QAAK,KAAK,YAAY,OAAO,GAAG,YAAY,KAAK,gBAAgB;AAC1E"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { repositoryId, repositoryLabel } from "../repositoryIdentity/index.mjs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import "@agimon-ai/doompi-core/web";
|
|
5
|
+
//#region src/services/paths/index.ts
|
|
6
|
+
/**
|
|
7
|
+
* Where this package keeps its own state.
|
|
8
|
+
*
|
|
9
|
+
* Outside the repository on purpose. A worktree directory inside the checkout
|
|
10
|
+
* would be found by every glob the repository's own tooling runs, and would
|
|
11
|
+
* resolve workspace imports against the parent checkout rather than the
|
|
12
|
+
* worktree, so a session there would build the wrong source while appearing to
|
|
13
|
+
* work.
|
|
14
|
+
*/
|
|
15
|
+
function doomGitRoot(homeDir = os.homedir()) {
|
|
16
|
+
return path.join(homeDir, ".pi", ".doom", "git");
|
|
17
|
+
}
|
|
18
|
+
/** The directory every worktree for every repository is created under. */
|
|
19
|
+
function worktreesRoot(homeDir = os.homedir()) {
|
|
20
|
+
return path.join(doomGitRoot(homeDir), "worktrees");
|
|
21
|
+
}
|
|
22
|
+
/** One registry file per repository, keyed by the shared git directory. */
|
|
23
|
+
function registryFile(repositoryRoot, homeDir = os.homedir()) {
|
|
24
|
+
const key = `${repositoryLabel(repositoryRoot)}--${repositoryId(repositoryRoot)}`;
|
|
25
|
+
return path.join(doomGitRoot(homeDir), "registry", key, "worktrees.json");
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { doomGitRoot, registryFile, worktreesRoot };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/services/paths/index.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\n\nimport { REGISTRY_DIR_ENV, resolveRegistryDir } from '@agimon-ai/doompi-core/web';\n\nimport { repositoryId, repositoryLabel } from '../repositoryIdentity';\n\nconst REGISTRY_DIR_FLAG = '--registry-dir';\n\n/**\n * Where this package keeps its own state.\n *\n * Outside the repository on purpose. A worktree directory inside the checkout\n * would be found by every glob the repository's own tooling runs, and would\n * resolve workspace imports against the parent checkout rather than the\n * worktree, so a session there would build the wrong source while appearing to\n * work.\n */\nexport function doomGitRoot(homeDir: string = os.homedir()): string {\n return path.join(homeDir, '.pi', '.doom', 'git');\n}\n\n/** The directory every worktree for every repository is created under. */\nexport function worktreesRoot(homeDir: string = os.homedir()): string {\n return path.join(doomGitRoot(homeDir), 'worktrees');\n}\n\n/** One registry file per repository, keyed by the shared git directory. */\n\nexport function registryFile(repositoryRoot: string, homeDir: string = os.homedir()): string {\n const key = `${repositoryLabel(repositoryRoot)}--${repositoryId(repositoryRoot)}`;\n return path.join(doomGitRoot(homeDir), 'registry', key, 'worktrees.json');\n}\n\n/**\n * The session registry directory this process's hub is watching.\n *\n * A spawned session only appears in the rail if it registers in the same\n * directory the hub watches, and the hub passes that directory to its children\n * as `--registry-dir` while also inheriting the env var. Recovering it from\n * this process's own argv and env, in the same precedence the hub and the\n * session server use, is what makes a worktree session visible rather than\n * silently invisible.\n */\nexport function hubRegistryDir(\n argv: readonly string[] = process.argv,\n env: NodeJS.ProcessEnv = process.env,\n homeDir: string = os.homedir(),\n): string {\n const index = argv.indexOf(REGISTRY_DIR_FLAG);\n const flagValue = index >= 0 ? argv[index + 1] : undefined;\n return resolveRegistryDir({\n ...(flagValue === undefined ? {} : { flagValue }),\n ...(env[REGISTRY_DIR_ENV] === undefined ? {} : { envValue: env[REGISTRY_DIR_ENV] }),\n homeDir,\n });\n}\n"],"mappings":";;;;;;;;;;;;;;AAkBA,SAAgB,YAAY,UAAkB,GAAG,QAAQ,GAAW;CAClE,OAAO,KAAK,KAAK,SAAS,OAAO,SAAS,KAAK;AACjD;;AAGA,SAAgB,cAAc,UAAkB,GAAG,QAAQ,GAAW;CACpE,OAAO,KAAK,KAAK,YAAY,OAAO,GAAG,WAAW;AACpD;;AAIA,SAAgB,aAAa,gBAAwB,UAAkB,GAAG,QAAQ,GAAW;CAC3F,MAAM,MAAM,GAAG,gBAAgB,cAAc,EAAE,IAAI,aAAa,cAAc;CAC9E,OAAO,KAAK,KAAK,YAAY,OAAO,GAAG,YAAY,KAAK,gBAAgB;AAC1E"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
let node_fs = require("node:fs");
|
|
3
|
+
node_fs = require_runtime.__toESM(node_fs, 1);
|
|
4
|
+
let node_crypto = require("node:crypto");
|
|
5
|
+
let node_path = require("node:path");
|
|
6
|
+
node_path = require_runtime.__toESM(node_path, 1);
|
|
7
|
+
//#region src/services/repositoryIdentity/index.ts
|
|
8
|
+
const ID_LENGTH = 12;
|
|
9
|
+
const MAX_LABEL_LENGTH = 32;
|
|
10
|
+
/**
|
|
11
|
+
* The git directory shared by a repository and all of its worktrees.
|
|
12
|
+
*
|
|
13
|
+
* A normal checkout has a `.git` directory. A linked worktree has a `.git`
|
|
14
|
+
* FILE pointing at `<common>/worktrees/<name>`, whose `commondir` points back
|
|
15
|
+
* at the shared directory. Following that chain is what makes every worktree of
|
|
16
|
+
* one repository agree on the repository's identity, which matters here because
|
|
17
|
+
* the registry is per repository and must be found from inside a worktree too.
|
|
18
|
+
*/
|
|
19
|
+
function gitCommonDirectory(root) {
|
|
20
|
+
const marker = node_path.default.join(root, ".git");
|
|
21
|
+
let stat;
|
|
22
|
+
try {
|
|
23
|
+
stat = node_fs.default.statSync(marker);
|
|
24
|
+
} catch {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (stat.isDirectory()) return marker;
|
|
28
|
+
let pointer;
|
|
29
|
+
try {
|
|
30
|
+
pointer = node_fs.default.readFileSync(marker, "utf8").trim();
|
|
31
|
+
} catch {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (!pointer.startsWith("gitdir:")) return void 0;
|
|
35
|
+
const gitDir = node_path.default.resolve(root, pointer.slice(7).trim());
|
|
36
|
+
try {
|
|
37
|
+
const common = node_fs.default.readFileSync(node_path.default.join(gitDir, "commondir"), "utf8").trim();
|
|
38
|
+
return node_path.default.resolve(gitDir, common);
|
|
39
|
+
} catch {
|
|
40
|
+
return gitDir;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** A directory name that is recognisable to a person and safe on a filesystem. */
|
|
44
|
+
function repositoryLabel(root) {
|
|
45
|
+
const label = node_path.default.basename(root).toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "").slice(0, MAX_LABEL_LENGTH);
|
|
46
|
+
return label === "" ? "repository" : label;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A stable id for the repository a directory belongs to.
|
|
50
|
+
*
|
|
51
|
+
* Keyed on the common git directory rather than the given path, so the main
|
|
52
|
+
* checkout and every worktree of it resolve to one id and therefore to one
|
|
53
|
+
* registry. Falling back to the path keeps a non-repository directory usable
|
|
54
|
+
* instead of failing, though nothing here should reach that case.
|
|
55
|
+
*/
|
|
56
|
+
function repositoryId(root) {
|
|
57
|
+
const common = gitCommonDirectory(root);
|
|
58
|
+
const token = common === void 0 ? `root:${node_path.default.resolve(root)}` : `git:${common}`;
|
|
59
|
+
return (0, node_crypto.createHash)("sha256").update(token).digest("hex").slice(0, ID_LENGTH);
|
|
60
|
+
}
|
|
61
|
+
/** A short, collision-resistant suffix for one worktree directory. */
|
|
62
|
+
function shortId(seed) {
|
|
63
|
+
return (0, node_crypto.createHash)("sha256").update(seed).digest("hex").slice(0, 8);
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
exports.gitCommonDirectory = gitCommonDirectory;
|
|
67
|
+
exports.repositoryId = repositoryId;
|
|
68
|
+
exports.repositoryLabel = repositoryLabel;
|
|
69
|
+
exports.shortId = shortId;
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["path","fs","createHash"],"sources":["../../../../src/services/repositoryIdentity/index.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nconst ID_LENGTH = 12;\nconst MAX_LABEL_LENGTH = 32;\n\n/**\n * The git directory shared by a repository and all of its worktrees.\n *\n * A normal checkout has a `.git` directory. A linked worktree has a `.git`\n * FILE pointing at `<common>/worktrees/<name>`, whose `commondir` points back\n * at the shared directory. Following that chain is what makes every worktree of\n * one repository agree on the repository's identity, which matters here because\n * the registry is per repository and must be found from inside a worktree too.\n */\nexport function gitCommonDirectory(root: string): string | undefined {\n const marker = path.join(root, '.git');\n let stat: fs.Stats;\n try {\n stat = fs.statSync(marker);\n } catch {\n return undefined;\n }\n if (stat.isDirectory()) return marker;\n let pointer: string;\n try {\n pointer = fs.readFileSync(marker, 'utf8').trim();\n } catch {\n return undefined;\n }\n if (!pointer.startsWith('gitdir:')) return undefined;\n const gitDir = path.resolve(root, pointer.slice('gitdir:'.length).trim());\n try {\n const common = fs.readFileSync(path.join(gitDir, 'commondir'), 'utf8').trim();\n return path.resolve(gitDir, common);\n } catch {\n // A submodule's .git file has no commondir; its gitdir is already common.\n return gitDir;\n }\n}\n\n/** A directory name that is recognisable to a person and safe on a filesystem. */\nexport function repositoryLabel(root: string): string {\n const label = path\n .basename(root)\n .toLowerCase()\n .replace(/[^a-z0-9]+/gu, '-')\n .replace(/^-+|-+$/gu, '')\n .slice(0, MAX_LABEL_LENGTH);\n return label === '' ? 'repository' : label;\n}\n\n/**\n * A stable id for the repository a directory belongs to.\n *\n * Keyed on the common git directory rather than the given path, so the main\n * checkout and every worktree of it resolve to one id and therefore to one\n * registry. Falling back to the path keeps a non-repository directory usable\n * instead of failing, though nothing here should reach that case.\n */\nexport function repositoryId(root: string): string {\n const common = gitCommonDirectory(root);\n const token = common === undefined ? `root:${path.resolve(root)}` : `git:${common}`;\n return createHash('sha256').update(token).digest('hex').slice(0, ID_LENGTH);\n}\n\n/** A short, collision-resistant suffix for one worktree directory. */\nexport function shortId(seed: string): string {\n return createHash('sha256').update(seed).digest('hex').slice(0, 8);\n}\n"],"mappings":";;;;;;;AAIA,MAAM,YAAY;AAClB,MAAM,mBAAmB;;;;;;;;;;AAWzB,SAAgB,mBAAmB,MAAkC;CACnE,MAAM,SAASA,UAAAA,QAAK,KAAK,MAAM,MAAM;CACrC,IAAI;CACJ,IAAI;EACF,OAAOC,QAAAA,QAAG,SAAS,MAAM;CAC3B,QAAQ;EACN;CACF;CACA,IAAI,KAAK,YAAY,GAAG,OAAO;CAC/B,IAAI;CACJ,IAAI;EACF,UAAUA,QAAAA,QAAG,aAAa,QAAQ,MAAM,CAAC,CAAC,KAAK;CACjD,QAAQ;EACN;CACF;CACA,IAAI,CAAC,QAAQ,WAAW,SAAS,GAAG,OAAO,KAAA;CAC3C,MAAM,SAASD,UAAAA,QAAK,QAAQ,MAAM,QAAQ,MAAM,CAAgB,CAAC,CAAC,KAAK,CAAC;CACxE,IAAI;EACF,MAAM,SAASC,QAAAA,QAAG,aAAaD,UAAAA,QAAK,KAAK,QAAQ,WAAW,GAAG,MAAM,CAAC,CAAC,KAAK;EAC5E,OAAOA,UAAAA,QAAK,QAAQ,QAAQ,MAAM;CACpC,QAAQ;EAEN,OAAO;CACT;AACF;;AAGA,SAAgB,gBAAgB,MAAsB;CACpD,MAAM,QAAQA,UAAAA,QACX,SAAS,IAAI,CAAC,CACd,YAAY,CAAC,CACb,QAAQ,gBAAgB,GAAG,CAAC,CAC5B,QAAQ,aAAa,EAAE,CAAC,CACxB,MAAM,GAAG,gBAAgB;CAC5B,OAAO,UAAU,KAAK,eAAe;AACvC;;;;;;;;;AAUA,SAAgB,aAAa,MAAsB;CACjD,MAAM,SAAS,mBAAmB,IAAI;CACtC,MAAM,QAAQ,WAAW,KAAA,IAAY,QAAQA,UAAAA,QAAK,QAAQ,IAAI,MAAM,OAAO;CAC3E,QAAA,GAAOE,YAAAA,WAAAA,CAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,SAAS;AAC5E;;AAGA,SAAgB,QAAQ,MAAsB;CAC5C,QAAA,GAAOA,YAAAA,WAAAA,CAAW,QAAQ,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC;AACnE"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
//#region src/services/repositoryIdentity/index.ts
|
|
5
|
+
const ID_LENGTH = 12;
|
|
6
|
+
const MAX_LABEL_LENGTH = 32;
|
|
7
|
+
/**
|
|
8
|
+
* The git directory shared by a repository and all of its worktrees.
|
|
9
|
+
*
|
|
10
|
+
* A normal checkout has a `.git` directory. A linked worktree has a `.git`
|
|
11
|
+
* FILE pointing at `<common>/worktrees/<name>`, whose `commondir` points back
|
|
12
|
+
* at the shared directory. Following that chain is what makes every worktree of
|
|
13
|
+
* one repository agree on the repository's identity, which matters here because
|
|
14
|
+
* the registry is per repository and must be found from inside a worktree too.
|
|
15
|
+
*/
|
|
16
|
+
function gitCommonDirectory(root) {
|
|
17
|
+
const marker = path.join(root, ".git");
|
|
18
|
+
let stat;
|
|
19
|
+
try {
|
|
20
|
+
stat = fs.statSync(marker);
|
|
21
|
+
} catch {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (stat.isDirectory()) return marker;
|
|
25
|
+
let pointer;
|
|
26
|
+
try {
|
|
27
|
+
pointer = fs.readFileSync(marker, "utf8").trim();
|
|
28
|
+
} catch {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (!pointer.startsWith("gitdir:")) return void 0;
|
|
32
|
+
const gitDir = path.resolve(root, pointer.slice(7).trim());
|
|
33
|
+
try {
|
|
34
|
+
const common = fs.readFileSync(path.join(gitDir, "commondir"), "utf8").trim();
|
|
35
|
+
return path.resolve(gitDir, common);
|
|
36
|
+
} catch {
|
|
37
|
+
return gitDir;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** A directory name that is recognisable to a person and safe on a filesystem. */
|
|
41
|
+
function repositoryLabel(root) {
|
|
42
|
+
const label = path.basename(root).toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "").slice(0, MAX_LABEL_LENGTH);
|
|
43
|
+
return label === "" ? "repository" : label;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A stable id for the repository a directory belongs to.
|
|
47
|
+
*
|
|
48
|
+
* Keyed on the common git directory rather than the given path, so the main
|
|
49
|
+
* checkout and every worktree of it resolve to one id and therefore to one
|
|
50
|
+
* registry. Falling back to the path keeps a non-repository directory usable
|
|
51
|
+
* instead of failing, though nothing here should reach that case.
|
|
52
|
+
*/
|
|
53
|
+
function repositoryId(root) {
|
|
54
|
+
const common = gitCommonDirectory(root);
|
|
55
|
+
const token = common === void 0 ? `root:${path.resolve(root)}` : `git:${common}`;
|
|
56
|
+
return createHash("sha256").update(token).digest("hex").slice(0, ID_LENGTH);
|
|
57
|
+
}
|
|
58
|
+
/** A short, collision-resistant suffix for one worktree directory. */
|
|
59
|
+
function shortId(seed) {
|
|
60
|
+
return createHash("sha256").update(seed).digest("hex").slice(0, 8);
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { gitCommonDirectory, repositoryId, repositoryLabel, shortId };
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/services/repositoryIdentity/index.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nconst ID_LENGTH = 12;\nconst MAX_LABEL_LENGTH = 32;\n\n/**\n * The git directory shared by a repository and all of its worktrees.\n *\n * A normal checkout has a `.git` directory. A linked worktree has a `.git`\n * FILE pointing at `<common>/worktrees/<name>`, whose `commondir` points back\n * at the shared directory. Following that chain is what makes every worktree of\n * one repository agree on the repository's identity, which matters here because\n * the registry is per repository and must be found from inside a worktree too.\n */\nexport function gitCommonDirectory(root: string): string | undefined {\n const marker = path.join(root, '.git');\n let stat: fs.Stats;\n try {\n stat = fs.statSync(marker);\n } catch {\n return undefined;\n }\n if (stat.isDirectory()) return marker;\n let pointer: string;\n try {\n pointer = fs.readFileSync(marker, 'utf8').trim();\n } catch {\n return undefined;\n }\n if (!pointer.startsWith('gitdir:')) return undefined;\n const gitDir = path.resolve(root, pointer.slice('gitdir:'.length).trim());\n try {\n const common = fs.readFileSync(path.join(gitDir, 'commondir'), 'utf8').trim();\n return path.resolve(gitDir, common);\n } catch {\n // A submodule's .git file has no commondir; its gitdir is already common.\n return gitDir;\n }\n}\n\n/** A directory name that is recognisable to a person and safe on a filesystem. */\nexport function repositoryLabel(root: string): string {\n const label = path\n .basename(root)\n .toLowerCase()\n .replace(/[^a-z0-9]+/gu, '-')\n .replace(/^-+|-+$/gu, '')\n .slice(0, MAX_LABEL_LENGTH);\n return label === '' ? 'repository' : label;\n}\n\n/**\n * A stable id for the repository a directory belongs to.\n *\n * Keyed on the common git directory rather than the given path, so the main\n * checkout and every worktree of it resolve to one id and therefore to one\n * registry. Falling back to the path keeps a non-repository directory usable\n * instead of failing, though nothing here should reach that case.\n */\nexport function repositoryId(root: string): string {\n const common = gitCommonDirectory(root);\n const token = common === undefined ? `root:${path.resolve(root)}` : `git:${common}`;\n return createHash('sha256').update(token).digest('hex').slice(0, ID_LENGTH);\n}\n\n/** A short, collision-resistant suffix for one worktree directory. */\nexport function shortId(seed: string): string {\n return createHash('sha256').update(seed).digest('hex').slice(0, 8);\n}\n"],"mappings":";;;;AAIA,MAAM,YAAY;AAClB,MAAM,mBAAmB;;;;;;;;;;AAWzB,SAAgB,mBAAmB,MAAkC;CACnE,MAAM,SAAS,KAAK,KAAK,MAAM,MAAM;CACrC,IAAI;CACJ,IAAI;EACF,OAAO,GAAG,SAAS,MAAM;CAC3B,QAAQ;EACN;CACF;CACA,IAAI,KAAK,YAAY,GAAG,OAAO;CAC/B,IAAI;CACJ,IAAI;EACF,UAAU,GAAG,aAAa,QAAQ,MAAM,CAAC,CAAC,KAAK;CACjD,QAAQ;EACN;CACF;CACA,IAAI,CAAC,QAAQ,WAAW,SAAS,GAAG,OAAO,KAAA;CAC3C,MAAM,SAAS,KAAK,QAAQ,MAAM,QAAQ,MAAM,CAAgB,CAAC,CAAC,KAAK,CAAC;CACxE,IAAI;EACF,MAAM,SAAS,GAAG,aAAa,KAAK,KAAK,QAAQ,WAAW,GAAG,MAAM,CAAC,CAAC,KAAK;EAC5E,OAAO,KAAK,QAAQ,QAAQ,MAAM;CACpC,QAAQ;EAEN,OAAO;CACT;AACF;;AAGA,SAAgB,gBAAgB,MAAsB;CACpD,MAAM,QAAQ,KACX,SAAS,IAAI,CAAC,CACd,YAAY,CAAC,CACb,QAAQ,gBAAgB,GAAG,CAAC,CAC5B,QAAQ,aAAa,EAAE,CAAC,CACxB,MAAM,GAAG,gBAAgB;CAC5B,OAAO,UAAU,KAAK,eAAe;AACvC;;;;;;;;;AAUA,SAAgB,aAAa,MAAsB;CACjD,MAAM,SAAS,mBAAmB,IAAI;CACtC,MAAM,QAAQ,WAAW,KAAA,IAAY,QAAQ,KAAK,QAAQ,IAAI,MAAM,OAAO;CAC3E,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,SAAS;AAC5E;;AAGA,SAAgB,QAAQ,MAAsB;CAC5C,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC;AACnE"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
const require_index = require("../errors/index.cjs");
|
|
2
|
+
const require_runWorktreeTool = require("../../schemas/runWorktreeTool.cjs");
|
|
3
|
+
//#region src/services/runWorktree/index.ts
|
|
4
|
+
const RUN_WORKTREE_TOOL_NAME = "run_worktree";
|
|
5
|
+
const IMPLEMENTED_ACTIONS = new Set(Object.values(require_runWorktreeTool.WORKTREE_ACTIONS));
|
|
6
|
+
const RUN_WORKTREE_DESCRIPTION = `Create and manage git worktrees, each with its own DoomPi session nested under this one.
|
|
7
|
+
|
|
8
|
+
Actions:
|
|
9
|
+
- spawn_worktree: create a worktree on a new branch and start a session in it. Requires 'branch'. Optional 'baseRef' (defaults to the current branch), 'name' for the rail, 'task' as the first message.
|
|
10
|
+
- close_worktree: stop a worktree's session and delete its directory. Requires 'id'. Refuses a dirty tree unless 'force' is true.
|
|
11
|
+
- list: every worktree for this repository, with status.
|
|
12
|
+
- status: one worktree and its uncommitted files. Requires 'id'.
|
|
13
|
+
- merge: merge a worktree's branch into this checkout. Requires 'id'. Refuses when this checkout is dirty.
|
|
14
|
+
- prune: remove orphaned worktrees. Pass 'dryRun' to see the plan without destroying anything.
|
|
15
|
+
- send: send a message to the other side of a worktree. Requires 'id' and 'message'.
|
|
16
|
+
- messages: read messages waiting for you from a worktree. Requires 'id'.
|
|
17
|
+
|
|
18
|
+
Worktrees live outside the repository, under ~/.pi/.doom/git/worktrees.`;
|
|
19
|
+
/** Rejects calls that do not match one documented action shape. */
|
|
20
|
+
function validateParams(input) {
|
|
21
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) throw require_index.invalidRequest("run_worktree parameters must be an object.", "Call it with one documented action shape.");
|
|
22
|
+
const record = input;
|
|
23
|
+
const action = record.action;
|
|
24
|
+
if (typeof action !== "string" || !IMPLEMENTED_ACTIONS.has(action)) throw require_index.invalidRequest(`Unknown action ${typeof action === "string" ? `'${action}'` : "value"}.`, `Use one of: ${[...IMPLEMENTED_ACTIONS].join(", ")}.`);
|
|
25
|
+
const allowed = require_runWorktreeTool.WORKTREE_ACTION_FIELDS[action];
|
|
26
|
+
const unexpected = Object.keys(record).filter((key) => !allowed.includes(key));
|
|
27
|
+
if (unexpected.length > 0) throw require_index.invalidRequest(`action='${action}' does not accept: ${unexpected.join(", ")}.`, `Fields for '${action}': ${allowed.join(", ")}.`);
|
|
28
|
+
for (const field of ["branch", "id"]) if (allowed.includes(field) && field in record) {
|
|
29
|
+
const value = record[field];
|
|
30
|
+
if (typeof value !== "string" || value.trim() === "") throw require_index.invalidRequest(`action='${action}' requires a nonblank '${field}'.`, `Pass a ${field}.`);
|
|
31
|
+
}
|
|
32
|
+
for (const field of [
|
|
33
|
+
"baseRef",
|
|
34
|
+
"name",
|
|
35
|
+
"task",
|
|
36
|
+
"message"
|
|
37
|
+
]) if (field in record && (typeof record[field] !== "string" || record[field].trim() === "")) throw require_index.invalidRequest(`action='${action}' requires a nonblank '${field}'.`, `Pass a ${field}.`);
|
|
38
|
+
for (const field of ["force", "dryRun"]) if (field in record && typeof record[field] !== "boolean") throw require_index.invalidRequest(`action='${action}' requires boolean '${field}'.`, `Pass true or false for ${field}.`);
|
|
39
|
+
if (action === require_runWorktreeTool.WORKTREE_ACTIONS.send && typeof record.message !== "string") throw require_index.invalidRequest("action='send' requires 'message'.", "Pass the message to send.");
|
|
40
|
+
if (action === require_runWorktreeTool.WORKTREE_ACTIONS.spawn_worktree && typeof record.branch !== "string") throw require_index.invalidRequest("action='spawn_worktree' requires 'branch'.", "Name the branch to create.");
|
|
41
|
+
if ((action === require_runWorktreeTool.WORKTREE_ACTIONS.close_worktree || action === require_runWorktreeTool.WORKTREE_ACTIONS.status || action === require_runWorktreeTool.WORKTREE_ACTIONS.merge || action === require_runWorktreeTool.WORKTREE_ACTIONS.send || action === require_runWorktreeTool.WORKTREE_ACTIONS.messages) && typeof record.id !== "string") throw require_index.invalidRequest(`action='${action}' requires 'id'.`, "Call list to see the current ids.");
|
|
42
|
+
return record;
|
|
43
|
+
}
|
|
44
|
+
function describe(record) {
|
|
45
|
+
return `${record.id} ${record.branch} ${record.status} ${record.path}`;
|
|
46
|
+
}
|
|
47
|
+
function text(...lines) {
|
|
48
|
+
return [{
|
|
49
|
+
type: "text",
|
|
50
|
+
text: lines.join("\n")
|
|
51
|
+
}];
|
|
52
|
+
}
|
|
53
|
+
async function executeRunWorktreeTool(params, operations, context, options = {}) {
|
|
54
|
+
switch (params.action) {
|
|
55
|
+
case require_runWorktreeTool.WORKTREE_ACTIONS.spawn_worktree: {
|
|
56
|
+
const record = await operations.spawn(context, {
|
|
57
|
+
branch: params.branch,
|
|
58
|
+
...params.baseRef === void 0 ? {} : { baseRef: params.baseRef },
|
|
59
|
+
...params.name === void 0 ? {} : { name: params.name }
|
|
60
|
+
}, options);
|
|
61
|
+
return {
|
|
62
|
+
content: text(`Worktree ${record.id} created on ${record.branch} from ${record.baseRef}.`, `Path: ${record.path}`, `Session ${record.sessionId} is starting; it appears nested under this one in the rail.`),
|
|
63
|
+
details: {
|
|
64
|
+
action: params.action,
|
|
65
|
+
records: [record]
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
case require_runWorktreeTool.WORKTREE_ACTIONS.close_worktree: {
|
|
70
|
+
const record = await operations.close(context, params.id, params.force ?? false);
|
|
71
|
+
return {
|
|
72
|
+
content: text(`Worktree ${record.id} (${record.branch}) closed and removed.`),
|
|
73
|
+
details: {
|
|
74
|
+
action: params.action,
|
|
75
|
+
records: [record]
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
case require_runWorktreeTool.WORKTREE_ACTIONS.list: {
|
|
80
|
+
const records = await operations.list(context);
|
|
81
|
+
return {
|
|
82
|
+
content: records.length === 0 ? text("No worktrees for this repository.") : text(`${String(records.length)} worktree(s):`, ...records.map(describe)),
|
|
83
|
+
details: {
|
|
84
|
+
action: params.action,
|
|
85
|
+
records
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
case require_runWorktreeTool.WORKTREE_ACTIONS.status: {
|
|
90
|
+
const { record, dirtyFiles } = await operations.status(context, params.id);
|
|
91
|
+
return {
|
|
92
|
+
content: text(describe(record), `Session: ${record.sessionId}`, dirtyFiles.length === 0 ? "Clean." : `${String(dirtyFiles.length)} uncommitted file(s): ${dirtyFiles.slice(0, 20).join(", ")}`),
|
|
93
|
+
details: {
|
|
94
|
+
action: params.action,
|
|
95
|
+
records: [record]
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
case require_runWorktreeTool.WORKTREE_ACTIONS.merge: {
|
|
100
|
+
const record = await operations.merge(context, params.id, ...params.message === void 0 ? [] : [params.message]);
|
|
101
|
+
return {
|
|
102
|
+
content: text(`Merged ${record.branch} into this checkout.`),
|
|
103
|
+
details: {
|
|
104
|
+
action: params.action,
|
|
105
|
+
records: [record]
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
case require_runWorktreeTool.WORKTREE_ACTIONS.send:
|
|
110
|
+
await operations.send(context, params.id, params.message);
|
|
111
|
+
return {
|
|
112
|
+
content: text(`Message sent to worktree ${params.id}.`),
|
|
113
|
+
details: { action: params.action }
|
|
114
|
+
};
|
|
115
|
+
case require_runWorktreeTool.WORKTREE_ACTIONS.messages: {
|
|
116
|
+
const waiting = await operations.messages(context, params.id);
|
|
117
|
+
return {
|
|
118
|
+
content: waiting.length === 0 ? text("No messages.") : text(`${String(waiting.length)} message(s):`, ...waiting.map((entry) => `[${entry.sentAt}] ${entry.from}: ${entry.text}`)),
|
|
119
|
+
details: { action: params.action }
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
case require_runWorktreeTool.WORKTREE_ACTIONS.prune: {
|
|
123
|
+
const dryRun = params.dryRun ?? false;
|
|
124
|
+
const plan = await operations.prune(context, dryRun);
|
|
125
|
+
return {
|
|
126
|
+
content: text(...[
|
|
127
|
+
dryRun ? "Prune plan (nothing was changed):" : "Pruned:",
|
|
128
|
+
`Remove: ${plan.remove.length === 0 ? "none" : plan.remove.map((record) => record.id).join(", ")}`,
|
|
129
|
+
`Forget: ${plan.forget.length === 0 ? "none" : plan.forget.map((record) => record.id).join(", ")}`,
|
|
130
|
+
`Kept, uncommitted work: ${plan.keptDirty.length === 0 ? "none" : plan.keptDirty.map((record) => record.id).join(", ")}`,
|
|
131
|
+
`Untracked directories, left alone: ${plan.untracked.length === 0 ? "none" : plan.untracked.join(", ")}`,
|
|
132
|
+
...plan.keptBranches.length === 0 ? [] : [`Branches kept, they hold commits: ${plan.keptBranches.join(", ")}`]
|
|
133
|
+
]),
|
|
134
|
+
details: { action: params.action }
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//#endregion
|
|
140
|
+
exports.RUN_WORKTREE_DESCRIPTION = RUN_WORKTREE_DESCRIPTION;
|
|
141
|
+
exports.RUN_WORKTREE_TOOL_NAME = RUN_WORKTREE_TOOL_NAME;
|
|
142
|
+
exports.executeRunWorktreeTool = executeRunWorktreeTool;
|
|
143
|
+
exports.validateParams = validateParams;
|
|
144
|
+
|
|
145
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["WORKTREE_ACTIONS","invalidRequest","WORKTREE_ACTION_FIELDS"],"sources":["../../../../src/services/runWorktree/index.ts"],"sourcesContent":["import {\n RunWorktreeParams,\n WORKTREE_ACTION_FIELDS,\n WORKTREE_ACTIONS,\n type WorktreeAction,\n type RunWorktreeToolParams,\n} from '../../schemas/runWorktreeTool';\nimport type { WorktreeRecord } from '../../types/worktreeRegistry';\nimport { invalidRequest } from '../errors';\nimport type { WorktreeOperations } from '../worktreeOperations';\n\nexport { RunWorktreeParams };\nexport type { RunWorktreeToolParams, WorktreeAction };\n\nexport const RUN_WORKTREE_TOOL_NAME = 'run_worktree';\n\nconst IMPLEMENTED_ACTIONS: ReadonlySet<string> = new Set(Object.values(WORKTREE_ACTIONS));\n\nexport const RUN_WORKTREE_DESCRIPTION = `Create and manage git worktrees, each with its own DoomPi session nested under this one.\n\nActions:\n- spawn_worktree: create a worktree on a new branch and start a session in it. Requires 'branch'. Optional 'baseRef' (defaults to the current branch), 'name' for the rail, 'task' as the first message.\n- close_worktree: stop a worktree's session and delete its directory. Requires 'id'. Refuses a dirty tree unless 'force' is true.\n- list: every worktree for this repository, with status.\n- status: one worktree and its uncommitted files. Requires 'id'.\n- merge: merge a worktree's branch into this checkout. Requires 'id'. Refuses when this checkout is dirty.\n- prune: remove orphaned worktrees. Pass 'dryRun' to see the plan without destroying anything.\n- send: send a message to the other side of a worktree. Requires 'id' and 'message'.\n- messages: read messages waiting for you from a worktree. Requires 'id'.\n\nWorktrees live outside the repository, under ~/.pi/.doom/git/worktrees.`;\n\nexport interface RunWorktreeToolDetails {\n action: WorktreeAction;\n records?: WorktreeRecord[];\n}\n\nexport interface RunWorktreeToolResult {\n content: [{ type: 'text'; text: string }];\n details: RunWorktreeToolDetails;\n}\n\nexport interface RunWorktreeExecutionContext {\n readonly cwd: string;\n readonly sessionId: string;\n}\n\nexport interface RunWorktreeExecutionOptions {\n readonly signal?: AbortSignal;\n readonly onProgress?: (label: string) => void;\n}\n\n/** Rejects calls that do not match one documented action shape. */\nexport function validateParams(input: unknown): RunWorktreeToolParams {\n if (typeof input !== 'object' || input === null || Array.isArray(input)) {\n throw invalidRequest('run_worktree parameters must be an object.', 'Call it with one documented action shape.');\n }\n const record = input as Record<string, unknown>;\n const action = record.action;\n if (typeof action !== 'string' || !IMPLEMENTED_ACTIONS.has(action)) {\n throw invalidRequest(\n `Unknown action ${typeof action === 'string' ? `'${action}'` : 'value'}.`,\n `Use one of: ${[...IMPLEMENTED_ACTIONS].join(', ')}.`,\n );\n }\n const allowed = WORKTREE_ACTION_FIELDS[action as WorktreeAction];\n const unexpected = Object.keys(record).filter((key) => !allowed.includes(key));\n if (unexpected.length > 0) {\n throw invalidRequest(\n `action='${action}' does not accept: ${unexpected.join(', ')}.`,\n `Fields for '${action}': ${allowed.join(', ')}.`,\n );\n }\n for (const field of ['branch', 'id'] as const) {\n if (allowed.includes(field) && field in record) {\n const value = record[field];\n if (typeof value !== 'string' || value.trim() === '') {\n throw invalidRequest(`action='${action}' requires a nonblank '${field}'.`, `Pass a ${field}.`);\n }\n }\n }\n const stringFields = ['baseRef', 'name', 'task', 'message'] as const;\n for (const field of stringFields) {\n if (field in record && (typeof record[field] !== 'string' || record[field].trim() === '')) {\n throw invalidRequest(`action='${action}' requires a nonblank '${field}'.`, `Pass a ${field}.`);\n }\n }\n for (const field of ['force', 'dryRun'] as const) {\n if (field in record && typeof record[field] !== 'boolean') {\n throw invalidRequest(`action='${action}' requires boolean '${field}'.`, `Pass true or false for ${field}.`);\n }\n }\n if (action === WORKTREE_ACTIONS.send && typeof record.message !== 'string') {\n throw invalidRequest(\"action='send' requires 'message'.\", 'Pass the message to send.');\n }\n if (action === WORKTREE_ACTIONS.spawn_worktree && typeof record.branch !== 'string') {\n throw invalidRequest(\"action='spawn_worktree' requires 'branch'.\", 'Name the branch to create.');\n }\n if (\n (action === WORKTREE_ACTIONS.close_worktree ||\n action === WORKTREE_ACTIONS.status ||\n action === WORKTREE_ACTIONS.merge ||\n action === WORKTREE_ACTIONS.send ||\n action === WORKTREE_ACTIONS.messages) &&\n typeof record.id !== 'string'\n ) {\n throw invalidRequest(`action='${action}' requires 'id'.`, 'Call list to see the current ids.');\n }\n return record as RunWorktreeToolParams;\n}\n\nfunction describe(record: WorktreeRecord): string {\n return `${record.id} ${record.branch} ${record.status} ${record.path}`;\n}\n\nfunction text(...lines: readonly string[]): [{ type: 'text'; text: string }] {\n return [{ type: 'text', text: lines.join('\\n') }];\n}\n\nexport async function executeRunWorktreeTool(\n params: RunWorktreeToolParams,\n operations: WorktreeOperations,\n context: RunWorktreeExecutionContext,\n options: RunWorktreeExecutionOptions = {},\n): Promise<RunWorktreeToolResult> {\n switch (params.action) {\n case WORKTREE_ACTIONS.spawn_worktree: {\n const record = await operations.spawn(\n context,\n {\n branch: params.branch,\n ...(params.baseRef === undefined ? {} : { baseRef: params.baseRef }),\n ...(params.name === undefined ? {} : { name: params.name }),\n },\n options,\n );\n return {\n content: text(\n `Worktree ${record.id} created on ${record.branch} from ${record.baseRef}.`,\n `Path: ${record.path}`,\n `Session ${record.sessionId} is starting; it appears nested under this one in the rail.`,\n ),\n details: { action: params.action, records: [record] },\n };\n }\n case WORKTREE_ACTIONS.close_worktree: {\n const record = await operations.close(context, params.id, params.force ?? false);\n return {\n content: text(`Worktree ${record.id} (${record.branch}) closed and removed.`),\n details: { action: params.action, records: [record] },\n };\n }\n case WORKTREE_ACTIONS.list: {\n const records = await operations.list(context);\n return {\n content:\n records.length === 0\n ? text('No worktrees for this repository.')\n : text(`${String(records.length)} worktree(s):`, ...records.map(describe)),\n details: { action: params.action, records },\n };\n }\n case WORKTREE_ACTIONS.status: {\n const { record, dirtyFiles } = await operations.status(context, params.id);\n return {\n content: text(\n describe(record),\n `Session: ${record.sessionId}`,\n dirtyFiles.length === 0\n ? 'Clean.'\n : `${String(dirtyFiles.length)} uncommitted file(s): ${dirtyFiles.slice(0, 20).join(', ')}`,\n ),\n details: { action: params.action, records: [record] },\n };\n }\n case WORKTREE_ACTIONS.merge: {\n const record = await operations.merge(\n context,\n params.id,\n ...(params.message === undefined ? [] : ([params.message] as const)),\n );\n return {\n content: text(`Merged ${record.branch} into this checkout.`),\n details: { action: params.action, records: [record] },\n };\n }\n case WORKTREE_ACTIONS.send: {\n await operations.send(context, params.id, params.message);\n return { content: text(`Message sent to worktree ${params.id}.`), details: { action: params.action } };\n }\n case WORKTREE_ACTIONS.messages: {\n const waiting = await operations.messages(context, params.id);\n return {\n content:\n waiting.length === 0\n ? text('No messages.')\n : text(\n `${String(waiting.length)} message(s):`,\n ...waiting.map((entry) => `[${entry.sentAt}] ${entry.from}: ${entry.text}`),\n ),\n details: { action: params.action },\n };\n }\n case WORKTREE_ACTIONS.prune: {\n const dryRun = params.dryRun ?? false;\n const plan = await operations.prune(context, dryRun);\n const lines = [\n dryRun ? 'Prune plan (nothing was changed):' : 'Pruned:',\n `Remove: ${plan.remove.length === 0 ? 'none' : plan.remove.map((record) => record.id).join(', ')}`,\n `Forget: ${plan.forget.length === 0 ? 'none' : plan.forget.map((record) => record.id).join(', ')}`,\n `Kept, uncommitted work: ${plan.keptDirty.length === 0 ? 'none' : plan.keptDirty.map((record) => record.id).join(', ')}`,\n `Untracked directories, left alone: ${plan.untracked.length === 0 ? 'none' : plan.untracked.join(', ')}`,\n ...(plan.keptBranches.length === 0\n ? []\n : [`Branches kept, they hold commits: ${plan.keptBranches.join(', ')}`]),\n ];\n return { content: text(...lines), details: { action: params.action } };\n }\n }\n}\n"],"mappings":"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"}
|