@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.
- package/README.md +33 -1
- package/dist/apiContracts.cjs +387 -0
- package/dist/apiContracts.cjs.map +1 -0
- package/dist/apiContracts.d.mts +53 -0
- package/dist/apiContracts.d.mts.map +1 -0
- package/dist/apiContracts.mjs +382 -0
- package/dist/apiContracts.mjs.map +1 -0
- package/dist/extensions/pi.cjs +105 -1
- package/dist/extensions/pi.cjs.map +1 -0
- package/dist/extensions/pi.d.mts +6 -2
- package/dist/extensions/pi.d.mts.map +1 -0
- package/dist/extensions/pi.mjs +100 -1
- package/dist/extensions/pi.mjs.map +1 -0
- package/dist/extensions/server.cjs +1828 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +1820 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/extensions/web.mjs +2619 -0
- package/dist/extensions/web.mjs.map +1 -0
- package/dist/gitDependencies-CtVubYvU.mjs +22 -0
- package/dist/gitDependencies-CtVubYvU.mjs.map +1 -0
- package/dist/gitDependencies-Dqsz2HjK.cjs +33 -0
- package/dist/gitDependencies-Dqsz2HjK.cjs.map +1 -0
- package/dist/index-D79MSCee.d.mts +145 -0
- package/dist/index-D79MSCee.d.mts.map +1 -0
- package/dist/index.cjs +4 -1
- package/dist/index.d.mts +2 -5
- package/dist/index.mjs +2 -1
- package/dist/runWorktree-BE795LxL.cjs +374 -0
- package/dist/runWorktree-BE795LxL.cjs.map +1 -0
- package/dist/runWorktree-SPzJvIBt.mjs +303 -0
- package/dist/runWorktree-SPzJvIBt.mjs.map +1 -0
- package/dist/worktreeOperations-BYmVU0UV.cjs +1350 -0
- package/dist/worktreeOperations-BYmVU0UV.cjs.map +1 -0
- package/dist/worktreeOperations-BrWG2muV.mjs +1194 -0
- package/dist/worktreeOperations-BrWG2muV.mjs.map +1 -0
- package/llms.txt +4 -0
- package/package.json +56 -41
- package/src/prompts/doompi-use-git/SKILL.md +26 -3
- package/dist/_virtual/_rolldown/runtime.cjs +0 -1
- package/dist/adapters/channel/worktreeChannel.cjs +0 -2
- package/dist/adapters/channel/worktreeChannel.cjs.map +0 -1
- package/dist/adapters/channel/worktreeChannel.d.cts +0 -40
- package/dist/adapters/channel/worktreeChannel.d.cts.map +0 -1
- package/dist/adapters/channel/worktreeChannel.d.mts +0 -40
- package/dist/adapters/channel/worktreeChannel.d.mts.map +0 -1
- package/dist/adapters/channel/worktreeChannel.mjs +0 -2
- package/dist/adapters/channel/worktreeChannel.mjs.map +0 -1
- package/dist/adapters/filesystem/atomicJson.cjs +0 -2
- package/dist/adapters/filesystem/atomicJson.cjs.map +0 -1
- package/dist/adapters/filesystem/atomicJson.mjs +0 -2
- package/dist/adapters/filesystem/atomicJson.mjs.map +0 -1
- package/dist/adapters/filesystem/paths.cjs +0 -2
- package/dist/adapters/filesystem/paths.cjs.map +0 -1
- package/dist/adapters/filesystem/paths.mjs +0 -2
- package/dist/adapters/filesystem/paths.mjs.map +0 -1
- package/dist/adapters/hub/hubClient.cjs +0 -2
- package/dist/adapters/hub/hubClient.cjs.map +0 -1
- package/dist/adapters/hub/hubClient.d.cts +0 -1
- package/dist/adapters/hub/hubClient.d.mts +0 -1
- package/dist/adapters/hub/hubClient.mjs +0 -2
- package/dist/adapters/hub/hubClient.mjs.map +0 -1
- package/dist/adapters/pi/extension.cjs +0 -2
- package/dist/adapters/pi/extension.cjs.map +0 -1
- package/dist/adapters/pi/extension.d.cts +0 -9
- package/dist/adapters/pi/extension.d.cts.map +0 -1
- package/dist/adapters/pi/extension.d.mts +0 -9
- package/dist/adapters/pi/extension.d.mts.map +0 -1
- package/dist/adapters/pi/extension.mjs +0 -2
- package/dist/adapters/pi/extension.mjs.map +0 -1
- package/dist/adapters/pi/extensions/runWorktreeTool.cjs +0 -15
- package/dist/adapters/pi/extensions/runWorktreeTool.cjs.map +0 -1
- package/dist/adapters/pi/extensions/runWorktreeTool.mjs +0 -15
- package/dist/adapters/pi/extensions/runWorktreeTool.mjs.map +0 -1
- package/dist/adapters/web/worktreesChannel.cjs +0 -2
- package/dist/adapters/web/worktreesChannel.cjs.map +0 -1
- package/dist/adapters/web/worktreesChannel.d.cts +0 -21
- package/dist/adapters/web/worktreesChannel.d.cts.map +0 -1
- package/dist/adapters/web/worktreesChannel.d.mts +0 -21
- package/dist/adapters/web/worktreesChannel.d.mts.map +0 -1
- package/dist/adapters/web/worktreesChannel.mjs +0 -2
- package/dist/adapters/web/worktreesChannel.mjs.map +0 -1
- package/dist/adapters/worktree/dependencyInstall.cjs +0 -2
- package/dist/adapters/worktree/dependencyInstall.cjs.map +0 -1
- package/dist/adapters/worktree/dependencyInstall.mjs +0 -2
- package/dist/adapters/worktree/dependencyInstall.mjs.map +0 -1
- package/dist/adapters/worktree/gitCli.cjs +0 -4
- package/dist/adapters/worktree/gitCli.cjs.map +0 -1
- package/dist/adapters/worktree/gitCli.mjs +0 -4
- package/dist/adapters/worktree/gitCli.mjs.map +0 -1
- package/dist/adapters/worktree/repositoryIdentity.cjs +0 -2
- package/dist/adapters/worktree/repositoryIdentity.cjs.map +0 -1
- package/dist/adapters/worktree/repositoryIdentity.mjs +0 -2
- package/dist/adapters/worktree/repositoryIdentity.mjs.map +0 -1
- package/dist/adapters/worktree/worktreeOperations.cjs +0 -2
- package/dist/adapters/worktree/worktreeOperations.cjs.map +0 -1
- package/dist/adapters/worktree/worktreeOperations.d.cts +0 -32
- package/dist/adapters/worktree/worktreeOperations.d.cts.map +0 -1
- package/dist/adapters/worktree/worktreeOperations.d.mts +0 -32
- package/dist/adapters/worktree/worktreeOperations.d.mts.map +0 -1
- package/dist/adapters/worktree/worktreeOperations.mjs +0 -2
- package/dist/adapters/worktree/worktreeOperations.mjs.map +0 -1
- package/dist/adapters/worktree/worktreeRegistry.cjs +0 -2
- package/dist/adapters/worktree/worktreeRegistry.cjs.map +0 -1
- package/dist/adapters/worktree/worktreeRegistry.mjs +0 -2
- package/dist/adapters/worktree/worktreeRegistry.mjs.map +0 -1
- package/dist/commands/doomGitCommand.cjs +0 -2
- package/dist/commands/doomGitCommand.cjs.map +0 -1
- package/dist/commands/doomGitCommand.mjs +0 -2
- package/dist/commands/doomGitCommand.mjs.map +0 -1
- package/dist/container/index.cjs +0 -2
- package/dist/container/index.cjs.map +0 -1
- package/dist/container/index.d.cts +0 -6
- package/dist/container/index.d.cts.map +0 -1
- package/dist/container/index.d.mts +0 -6
- package/dist/container/index.d.mts.map +0 -1
- package/dist/container/index.mjs +0 -2
- package/dist/container/index.mjs.map +0 -1
- package/dist/extensions/pi.d.cts +0 -2
- package/dist/hubApi.cjs +0 -2
- package/dist/hubApi.cjs.map +0 -1
- package/dist/hubApi.d.cts +0 -6
- package/dist/hubApi.d.cts.map +0 -1
- package/dist/hubApi.d.mts +0 -6
- package/dist/hubApi.d.mts.map +0 -1
- package/dist/hubApi.mjs +0 -2
- package/dist/hubApi.mjs.map +0 -1
- package/dist/index.d.cts +0 -5
- 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/extensionService.cjs +0 -2
- package/dist/services/extensionService.cjs.map +0 -1
- package/dist/services/extensionService.d.cts +0 -8
- package/dist/services/extensionService.d.cts.map +0 -1
- package/dist/services/extensionService.d.mts +0 -8
- package/dist/services/extensionService.d.mts.map +0 -1
- package/dist/services/extensionService.mjs +0 -2
- package/dist/services/extensionService.mjs.map +0 -1
- package/dist/services/support/errors.cjs +0 -2
- package/dist/services/support/errors.cjs.map +0 -1
- package/dist/services/support/errors.mjs +0 -2
- package/dist/services/support/errors.mjs.map +0 -1
- package/dist/services/worktreeNaming.cjs +0 -2
- package/dist/services/worktreeNaming.cjs.map +0 -1
- package/dist/services/worktreeNaming.d.cts +0 -27
- package/dist/services/worktreeNaming.d.cts.map +0 -1
- package/dist/services/worktreeNaming.d.mts +0 -27
- package/dist/services/worktreeNaming.d.mts.map +0 -1
- package/dist/services/worktreeNaming.mjs +0 -2
- package/dist/services/worktreeNaming.mjs.map +0 -1
- package/dist/types/extension.d.cts +0 -17
- package/dist/types/extension.d.cts.map +0 -1
- package/dist/types/extension.d.mts +0 -17
- 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 +0 -41
- package/dist/types/worktreeRegistry.d.cts.map +0 -1
- package/dist/types/worktreeRegistry.d.mts +0 -41
- package/dist/types/worktreeRegistry.d.mts.map +0 -1
- package/dist/webHub.cjs +0 -1
- package/dist/webHub.d.cts +0 -2
- package/dist/webHub.d.mts +0 -2
- package/dist/webHub.mjs +0 -1
- package/src/exports/webClient.ts +0 -1
- package/src/types/webWorktrees.ts +0 -55
- package/src/types/worktreeRegistry.ts +0 -69
- package/src/web/components/RunWorktreeToolMessage.tsx +0 -37
- package/src/web/components/WorktreesActivitySection.tsx +0 -64
- package/src/web/components/WorktreesPanel.tsx +0 -125
- package/src/web/components/toolRenderers.ts +0 -7
- package/src/web/index.ts +0 -30
- package/src/web/stores/worktreesActivityStore.ts +0 -124
- package/src/web/tsconfig.json +0 -22
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import "@agimon-ai/doompi-session";
|
|
2
|
+
import "@agimon-ai/doompi-core/hubChannel";
|
|
3
|
+
//#region src/services/worktreeEvents/index.d.ts
|
|
4
|
+
declare const WORKTREE_MESSAGE_VERSION: 1;
|
|
5
|
+
type WorktreeMessageParty = 'parent' | 'child';
|
|
6
|
+
interface WorktreeMessage {
|
|
7
|
+
readonly version: typeof WORKTREE_MESSAGE_VERSION;
|
|
8
|
+
readonly worktreeId: string;
|
|
9
|
+
readonly fromSessionId: string;
|
|
10
|
+
readonly from: WorktreeMessageParty;
|
|
11
|
+
readonly text: string;
|
|
12
|
+
readonly sentAt: string;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/types/worktreeRegistry.d.ts
|
|
16
|
+
/**
|
|
17
|
+
* A worktree's lifecycle as this package sees it.
|
|
18
|
+
*
|
|
19
|
+
* `orphaned` is a finding, not a cleanup: the session process is gone or the
|
|
20
|
+
* directory has vanished, but the worktree may still hold uncommitted work, so
|
|
21
|
+
* the record is kept until someone decides what to do with it.
|
|
22
|
+
*/
|
|
23
|
+
type WorktreeStatus = 'spawning' | 'running' | 'closing' | 'orphaned';
|
|
24
|
+
declare const WORKTREE_RECORD_VERSION = 1;
|
|
25
|
+
interface WorktreeRecord {
|
|
26
|
+
version: typeof WORKTREE_RECORD_VERSION;
|
|
27
|
+
/** This registry's own id, distinct from the session id, and stable across restarts. */
|
|
28
|
+
id: string;
|
|
29
|
+
/** The branch checked out in the worktree. */
|
|
30
|
+
branch: string;
|
|
31
|
+
/** The ref the branch was created from, kept so a merge can name its base. */
|
|
32
|
+
baseRef: string;
|
|
33
|
+
/** Absolute path to the worktree directory. */
|
|
34
|
+
path: string;
|
|
35
|
+
/** Absolute path to the repository the worktree belongs to. */
|
|
36
|
+
repositoryRoot: string;
|
|
37
|
+
/** The session spawned into the worktree. */
|
|
38
|
+
sessionId: string;
|
|
39
|
+
/**
|
|
40
|
+
* The session that asked for the worktree; the rail nests one under the other.
|
|
41
|
+
* Absent for a worktree opened from the new-session dialog, which has no parent.
|
|
42
|
+
*/
|
|
43
|
+
parentSessionId?: string;
|
|
44
|
+
status: WorktreeStatus;
|
|
45
|
+
/** ISO 8601. */
|
|
46
|
+
createdAt: string;
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/services/worktreeNaming/index.d.ts
|
|
50
|
+
interface PrunePlan {
|
|
51
|
+
/** Orphans whose directory git still lists, safe to remove. */
|
|
52
|
+
remove: WorktreeRecord[];
|
|
53
|
+
/** Orphans whose directory is already gone; drop the record only. */
|
|
54
|
+
forget: WorktreeRecord[];
|
|
55
|
+
/** Paths git lists under our root that we have no record of; report, never touch. */
|
|
56
|
+
untracked: string[];
|
|
57
|
+
/** Orphans left alone because they still hold uncommitted work. */
|
|
58
|
+
keptDirty: WorktreeRecord[];
|
|
59
|
+
/**
|
|
60
|
+
* Branches git refused to delete because they hold commits.
|
|
61
|
+
*
|
|
62
|
+
* Filled by the prune itself, not by the plan: a dry run destroys nothing, so
|
|
63
|
+
* it has nothing to report here and leaves it empty.
|
|
64
|
+
*/
|
|
65
|
+
keptBranches: string[];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* What a prune would do, decided before anything is destroyed.
|
|
69
|
+
*
|
|
70
|
+
* Separating the plan from the execution is what makes dryRun honest and lets
|
|
71
|
+
* the destructive half be reviewed on its own.
|
|
72
|
+
*/
|
|
73
|
+
declare function planPrune(input: {
|
|
74
|
+
records: readonly WorktreeRecord[];
|
|
75
|
+
gitPaths: readonly string[];
|
|
76
|
+
worktreesRoot: string;
|
|
77
|
+
dirtyByPath: ReadonlyMap<string, readonly string[]>;
|
|
78
|
+
}): PrunePlan;
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region src/services/worktreeOperations/index.d.ts
|
|
81
|
+
interface WorktreeContext {
|
|
82
|
+
/** Where the calling session is working, used to find the repository. */
|
|
83
|
+
cwd: string;
|
|
84
|
+
/**
|
|
85
|
+
* The calling session, recorded as the new session's parent. Absent when the
|
|
86
|
+
* new-session dialog opens a top-level worktree session for the workspace.
|
|
87
|
+
*/
|
|
88
|
+
sessionId?: string;
|
|
89
|
+
}
|
|
90
|
+
interface SpawnWorktreeRequest {
|
|
91
|
+
branch: string;
|
|
92
|
+
baseRef?: string;
|
|
93
|
+
name?: string;
|
|
94
|
+
task?: string;
|
|
95
|
+
/** Host-owned execution setup, exposed by the UI rather than the agent tool. */
|
|
96
|
+
reservationId?: string;
|
|
97
|
+
/** `existing` checks out a branch that already exists instead of creating one from `baseRef`. */
|
|
98
|
+
checkout?: 'new' | 'existing';
|
|
99
|
+
/** With `existing`: the branch exists only on this remote; a local tracking branch is created. */
|
|
100
|
+
remote?: string;
|
|
101
|
+
}
|
|
102
|
+
interface SpawnOptions {
|
|
103
|
+
/** Aborted when the caller gives up, so a spawn nobody is waiting for stops. */
|
|
104
|
+
signal?: AbortSignal;
|
|
105
|
+
/** Phase labels, for a caller that can show them while the work runs. */
|
|
106
|
+
onProgress?: (label: string) => void;
|
|
107
|
+
}
|
|
108
|
+
interface WorktreeOperations {
|
|
109
|
+
spawn(context: WorktreeContext, request: SpawnWorktreeRequest, options?: SpawnOptions): Promise<WorktreeRecord>;
|
|
110
|
+
close(context: WorktreeContext, id: string, force: boolean): Promise<WorktreeRecord>;
|
|
111
|
+
list(context: WorktreeContext): Promise<WorktreeRecord[]>;
|
|
112
|
+
status(context: WorktreeContext, id: string): Promise<{
|
|
113
|
+
record: WorktreeRecord;
|
|
114
|
+
dirtyFiles: string[];
|
|
115
|
+
}>;
|
|
116
|
+
merge(context: WorktreeContext, id: string, message?: string): Promise<WorktreeRecord>;
|
|
117
|
+
prune(context: WorktreeContext, dryRun: boolean): Promise<ReturnType<typeof planPrune>>;
|
|
118
|
+
send(context: WorktreeContext, id: string, message: string): Promise<void>;
|
|
119
|
+
messages(context: WorktreeContext, id: string): Promise<WorktreeMessage[]>;
|
|
120
|
+
}
|
|
121
|
+
//#endregion
|
|
122
|
+
//#region src/types/extension.d.ts
|
|
123
|
+
type GitNotificationLevel = 'info';
|
|
124
|
+
interface GitExtensionResult {
|
|
125
|
+
message: string;
|
|
126
|
+
level: GitNotificationLevel;
|
|
127
|
+
}
|
|
128
|
+
interface GitExtensionService {
|
|
129
|
+
execute(): Promise<GitExtensionResult>;
|
|
130
|
+
}
|
|
131
|
+
interface GitExtensionDependencies {
|
|
132
|
+
service: GitExtensionService;
|
|
133
|
+
operations: WorktreeOperations;
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region src/services/extensionService/index.d.ts
|
|
137
|
+
declare class DefaultGitExtensionService implements GitExtensionService {
|
|
138
|
+
execute(): Promise<GitExtensionResult>;
|
|
139
|
+
}
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/services/gitDependencies/index.d.ts
|
|
142
|
+
declare function createGitDependencies(overrides?: Partial<GitExtensionDependencies>): GitExtensionDependencies;
|
|
143
|
+
//#endregion
|
|
144
|
+
export { GitExtensionService as a, GitExtensionResult as i, DefaultGitExtensionService as n, GitExtensionDependencies as r, createGitDependencies as t };
|
|
145
|
+
//# sourceMappingURL=index-D79MSCee.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-D79MSCee.d.mts","names":[],"sources":["../src/services/worktreeEvents/index.ts","../src/types/worktreeRegistry.ts","../src/services/worktreeNaming/index.ts","../src/services/worktreeOperations/index.ts","../src/types/extension.ts","../src/services/extensionService/index.ts","../src/services/gitDependencies/index.ts"],"mappings":";;;cASa;KASD;UAEK;WACN,gBAAgB;WAChB;WACA;WACA,MAAM;WACN;WACA;;;;;;;;;;;KCRC;cAEC;UAEI;EACf,gBAAgB;;EAEhB;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;EAKA;EACA,QAAQ;;EAER;;;;UC8De;;EAEf,QAAQ;;EAER,QAAQ;;EAER;;EAEA,WAAW;;;;;;;EAOX;;;;;;;;iBASc,UAAU;EACxB,kBAAkB;EAClB;EACA;EACA,aAAa;IACX;;;UClHa;;EAEf;;;;;EAKA;;UAGe;EACf;EACA;EACA;EACA;;EAEA;;EAEA;;EAEA;;UAGe;;EAEf,SAAS;;EAET,cAAc;;UAGC;EACf,MAAM,SAAS,iBAAiB,SAAS,sBAAsB,UAAU,eAAe,QAAQ;EAChG,MAAM,SAAS,iBAAiB,YAAY,iBAAiB,QAAQ;EACrE,KAAK,SAAS,kBAAkB,QAAQ;EACxC,OAAO,SAAS,iBAAiB,aAAa;IAAU,QAAQ;IAAgB;;EAChF,MAAM,SAAS,iBAAiB,YAAY,mBAAmB,QAAQ;EACvE,MAAM,SAAS,iBAAiB,kBAAkB,QAAQ,kBAAkB;EAC5E,KAAK,SAAS,iBAAiB,YAAY,kBAAkB;EAC7D,SAAS,SAAS,iBAAiB,aAAa,QAA9B;;;;KCvDR;UAEK;EACf;EACA,OAAO;;UAGQ;EACf,WAAW,QAAQ;;UAGJ;EACf,SAAS;EACT,YAAY;;;;cCbD,sCAAsC;EAC3C,WAAW,QAAQ;;;;iBCEX,sBAAsB,YAAW,QAAQ,4BAAiC"}
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_gitDependencies = require("./gitDependencies-Dqsz2HjK.cjs");
|
|
3
|
+
exports.DefaultGitExtensionService = require_gitDependencies.DefaultGitExtensionService;
|
|
4
|
+
exports.createGitDependencies = require_gitDependencies.createGitDependencies;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { DefaultGitExtensionService } from "./services/extensionService.mjs";
|
|
4
|
-
import { createGitContainer } from "./container/index.mjs";
|
|
5
|
-
export { DefaultGitExtensionService, type GitExtensionDependencies, type GitExtensionResult, type GitExtensionService, activateGitExtension, createGitContainer };
|
|
1
|
+
import { a as GitExtensionService, i as GitExtensionResult, n as DefaultGitExtensionService, r as GitExtensionDependencies, t as createGitDependencies } from "./index-D79MSCee.mjs";
|
|
2
|
+
export { DefaultGitExtensionService, type GitExtensionDependencies, type GitExtensionResult, type GitExtensionService, createGitDependencies };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import { n as DefaultGitExtensionService, t as createGitDependencies } from "./gitDependencies-CtVubYvU.mjs";
|
|
2
|
+
export { DefaultGitExtensionService, createGitDependencies };
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
const require_worktreeOperations = require("./worktreeOperations-BYmVU0UV.cjs");
|
|
2
|
+
let typebox = require("typebox");
|
|
3
|
+
//#region src/constants/git.ts
|
|
4
|
+
const COMMAND_NAME = "doom-git";
|
|
5
|
+
const COMMAND_DESCRIPTION = "Show git worktrees owned by this session";
|
|
6
|
+
/** Workspace-mounted routes behind the new-session dialog. */
|
|
7
|
+
const GIT_BRANCHES_PATH = "/branches";
|
|
8
|
+
const GIT_SESSIONS_PATH = "/sessions";
|
|
9
|
+
/** Workspace-mounted: that workspace's remote auth for manual pull, push and rebase. */
|
|
10
|
+
const GIT_AUTH_PATH = "/auth";
|
|
11
|
+
/** Session-mounted: the session's change against its base, and one file's hunks. */
|
|
12
|
+
const GIT_REVIEW_PATH = "/review";
|
|
13
|
+
const GIT_REVIEW_FILE_PATH = "/review/file";
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/schemas/runWorktreeTool.ts
|
|
16
|
+
/**
|
|
17
|
+
* The tool's action vocabulary.
|
|
18
|
+
*
|
|
19
|
+
* One tool with an action field rather than six tools, matching `subagent`:
|
|
20
|
+
* the actions share a subject and are meaningless apart from it, and six
|
|
21
|
+
* separate tools would spend six description budgets teaching the same nouns.
|
|
22
|
+
*/
|
|
23
|
+
const WORKTREE_ACTIONS = {
|
|
24
|
+
spawn_worktree: "spawn_worktree",
|
|
25
|
+
close_worktree: "close_worktree",
|
|
26
|
+
list: "list",
|
|
27
|
+
status: "status",
|
|
28
|
+
merge: "merge",
|
|
29
|
+
prune: "prune",
|
|
30
|
+
send: "send",
|
|
31
|
+
messages: "messages"
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Which fields each action accepts.
|
|
35
|
+
*
|
|
36
|
+
* Rejecting an unknown field is what stops a plausible-looking call from doing
|
|
37
|
+
* something other than what it reads like: `close_worktree` with `branch`
|
|
38
|
+
* instead of `id` would otherwise close whatever the default resolved to.
|
|
39
|
+
*/
|
|
40
|
+
const WORKTREE_ACTION_FIELDS = {
|
|
41
|
+
spawn_worktree: [
|
|
42
|
+
"action",
|
|
43
|
+
"branch",
|
|
44
|
+
"baseRef",
|
|
45
|
+
"task",
|
|
46
|
+
"name"
|
|
47
|
+
],
|
|
48
|
+
close_worktree: [
|
|
49
|
+
"action",
|
|
50
|
+
"id",
|
|
51
|
+
"force"
|
|
52
|
+
],
|
|
53
|
+
list: ["action"],
|
|
54
|
+
status: ["action", "id"],
|
|
55
|
+
merge: [
|
|
56
|
+
"action",
|
|
57
|
+
"id",
|
|
58
|
+
"message"
|
|
59
|
+
],
|
|
60
|
+
prune: ["action", "dryRun"],
|
|
61
|
+
send: [
|
|
62
|
+
"action",
|
|
63
|
+
"id",
|
|
64
|
+
"message"
|
|
65
|
+
],
|
|
66
|
+
messages: ["action", "id"]
|
|
67
|
+
};
|
|
68
|
+
const SpawnParams = typebox.Type.Object({
|
|
69
|
+
action: typebox.Type.Literal(WORKTREE_ACTIONS.spawn_worktree),
|
|
70
|
+
branch: typebox.Type.String({ minLength: 1 }),
|
|
71
|
+
baseRef: typebox.Type.Optional(typebox.Type.String({ minLength: 1 })),
|
|
72
|
+
task: typebox.Type.Optional(typebox.Type.String({ minLength: 1 })),
|
|
73
|
+
name: typebox.Type.Optional(typebox.Type.String({ minLength: 1 }))
|
|
74
|
+
}, { additionalProperties: false });
|
|
75
|
+
const CloseParams = typebox.Type.Object({
|
|
76
|
+
action: typebox.Type.Literal(WORKTREE_ACTIONS.close_worktree),
|
|
77
|
+
id: typebox.Type.String({ minLength: 1 }),
|
|
78
|
+
force: typebox.Type.Optional(typebox.Type.Boolean())
|
|
79
|
+
}, { additionalProperties: false });
|
|
80
|
+
const ListParams = typebox.Type.Object({ action: typebox.Type.Literal(WORKTREE_ACTIONS.list) }, { additionalProperties: false });
|
|
81
|
+
const StatusParams = typebox.Type.Object({
|
|
82
|
+
action: typebox.Type.Literal(WORKTREE_ACTIONS.status),
|
|
83
|
+
id: typebox.Type.String({ minLength: 1 })
|
|
84
|
+
}, { additionalProperties: false });
|
|
85
|
+
const MergeParams = typebox.Type.Object({
|
|
86
|
+
action: typebox.Type.Literal(WORKTREE_ACTIONS.merge),
|
|
87
|
+
id: typebox.Type.String({ minLength: 1 }),
|
|
88
|
+
message: typebox.Type.Optional(typebox.Type.String({ minLength: 1 }))
|
|
89
|
+
}, { additionalProperties: false });
|
|
90
|
+
const PruneParams = typebox.Type.Object({
|
|
91
|
+
action: typebox.Type.Literal(WORKTREE_ACTIONS.prune),
|
|
92
|
+
dryRun: typebox.Type.Optional(typebox.Type.Boolean())
|
|
93
|
+
}, { additionalProperties: false });
|
|
94
|
+
const SendParams = typebox.Type.Object({
|
|
95
|
+
action: typebox.Type.Literal(WORKTREE_ACTIONS.send),
|
|
96
|
+
id: typebox.Type.String({ minLength: 1 }),
|
|
97
|
+
message: typebox.Type.String({ minLength: 1 })
|
|
98
|
+
}, { additionalProperties: false });
|
|
99
|
+
const MessagesParams = typebox.Type.Object({
|
|
100
|
+
action: typebox.Type.Literal(WORKTREE_ACTIONS.messages),
|
|
101
|
+
id: typebox.Type.String({ minLength: 1 })
|
|
102
|
+
}, { additionalProperties: false });
|
|
103
|
+
typebox.Type.Union([
|
|
104
|
+
SpawnParams,
|
|
105
|
+
CloseParams,
|
|
106
|
+
ListParams,
|
|
107
|
+
StatusParams,
|
|
108
|
+
MergeParams,
|
|
109
|
+
PruneParams,
|
|
110
|
+
SendParams,
|
|
111
|
+
MessagesParams
|
|
112
|
+
]);
|
|
113
|
+
/** The actions that accept `field`, so the declared docs cannot drift from the validator. */
|
|
114
|
+
function acceptingActions(field) {
|
|
115
|
+
return Object.values(WORKTREE_ACTIONS).filter((action) => WORKTREE_ACTION_FIELDS[action].includes(field)).join(", ");
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The schema declared to the model.
|
|
119
|
+
*
|
|
120
|
+
* A flat object rather than `RunWorktreeParams` itself. A top-level union is
|
|
121
|
+
* `{anyOf:[...]}` with no `properties`, and Pi's Anthropic Messages adapter
|
|
122
|
+
* rebuilds tool input as `{type:'object', properties: schema.properties ?? {},
|
|
123
|
+
* required: schema.required ?? []}`, so the union arrived at the model as an
|
|
124
|
+
* empty object while the host went on validating calls against it. Nothing here
|
|
125
|
+
* relaxes what is accepted: `validateParams` still rejects an unknown action, a
|
|
126
|
+
* field the action does not take, and a missing required one.
|
|
127
|
+
*/
|
|
128
|
+
const RunWorktreeToolSchema = typebox.Type.Object({
|
|
129
|
+
action: typebox.Type.String({
|
|
130
|
+
enum: Object.values(WORKTREE_ACTIONS),
|
|
131
|
+
description: "The operation to run. Every other field is accepted only by the actions its description names."
|
|
132
|
+
}),
|
|
133
|
+
branch: typebox.Type.Optional(typebox.Type.String({
|
|
134
|
+
minLength: 1,
|
|
135
|
+
description: `New branch to create. Actions: ${acceptingActions("branch")}.`
|
|
136
|
+
})),
|
|
137
|
+
baseRef: typebox.Type.Optional(typebox.Type.String({
|
|
138
|
+
minLength: 1,
|
|
139
|
+
description: `Base ref, defaulting to the current branch. Actions: ${acceptingActions("baseRef")}.`
|
|
140
|
+
})),
|
|
141
|
+
task: typebox.Type.Optional(typebox.Type.String({
|
|
142
|
+
minLength: 1,
|
|
143
|
+
description: `First message for the new session. Actions: ${acceptingActions("task")}.`
|
|
144
|
+
})),
|
|
145
|
+
name: typebox.Type.Optional(typebox.Type.String({
|
|
146
|
+
minLength: 1,
|
|
147
|
+
description: `Rail label for the worktree. Actions: ${acceptingActions("name")}.`
|
|
148
|
+
})),
|
|
149
|
+
id: typebox.Type.Optional(typebox.Type.String({
|
|
150
|
+
minLength: 1,
|
|
151
|
+
description: `Worktree id. Actions: ${acceptingActions("id")}.`
|
|
152
|
+
})),
|
|
153
|
+
force: typebox.Type.Optional(typebox.Type.Boolean({ description: `Close even when the tree is dirty. Actions: ${acceptingActions("force")}.` })),
|
|
154
|
+
message: typebox.Type.Optional(typebox.Type.String({
|
|
155
|
+
minLength: 1,
|
|
156
|
+
description: `Merge commit message, or the text to send. Actions: ${acceptingActions("message")}.`
|
|
157
|
+
})),
|
|
158
|
+
dryRun: typebox.Type.Optional(typebox.Type.Boolean({ description: `Report the plan without destroying anything. Actions: ${acceptingActions("dryRun")}.` }))
|
|
159
|
+
}, { additionalProperties: false });
|
|
160
|
+
//#endregion
|
|
161
|
+
//#region src/services/runWorktree/index.ts
|
|
162
|
+
const RUN_WORKTREE_TOOL_NAME = "run_worktree";
|
|
163
|
+
const IMPLEMENTED_ACTIONS = new Set(Object.values(WORKTREE_ACTIONS));
|
|
164
|
+
const RUN_WORKTREE_DESCRIPTION = `Create and manage git worktrees, each with its own DoomPi session nested under this one.
|
|
165
|
+
|
|
166
|
+
Actions:
|
|
167
|
+
- spawn_worktree: create a worktree on a new branch and start a session in it. Requires 'branch'. Optional 'baseRef' (defaults to the current branch's remote-tracking ref, then the remote default branch), 'name' for the rail, 'task' as the first message.
|
|
168
|
+
- close_worktree: stop a worktree's session, delete its checkout, and remove its generated sync storage. Requires 'id'. Refuses a dirty tree unless 'force' is true.
|
|
169
|
+
- list: every worktree for this repository, with status and relationship to the calling session.
|
|
170
|
+
- status: one worktree, its relationship to the calling session, and its uncommitted files. Requires 'id'.
|
|
171
|
+
- merge: merge a worktree's branch into this checkout. Requires 'id'. Refuses when this checkout is dirty.
|
|
172
|
+
- prune: remove orphaned worktrees and their generated sync storage. Pass 'dryRun' to see the plan without destroying anything.
|
|
173
|
+
- send: send a message to the other side of a worktree. Requires 'id' and 'message'.
|
|
174
|
+
- messages: read messages waiting for you from a worktree. Requires 'id'.
|
|
175
|
+
|
|
176
|
+
For a nested worktree session, use the record labelled 'child' in list to report to your parent. Use records labelled 'parent' to contact your own children. Other records are not communication edges.
|
|
177
|
+
Worktrees live outside the repository, under ~/.pi/.doom/git/worktrees.`;
|
|
178
|
+
/** Rejects calls that do not match one documented action shape. */
|
|
179
|
+
function validateParams(input) {
|
|
180
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) throw require_worktreeOperations.invalidRequest("run_worktree parameters must be an object.", "Call it with one documented action shape.");
|
|
181
|
+
const record = input;
|
|
182
|
+
const action = record.action;
|
|
183
|
+
if (typeof action !== "string" || !IMPLEMENTED_ACTIONS.has(action)) throw require_worktreeOperations.invalidRequest(`Unknown action ${typeof action === "string" ? `'${action}'` : "value"}.`, `Use one of: ${[...IMPLEMENTED_ACTIONS].join(", ")}.`);
|
|
184
|
+
const allowed = WORKTREE_ACTION_FIELDS[action];
|
|
185
|
+
const unexpected = Object.keys(record).filter((key) => !allowed.includes(key));
|
|
186
|
+
if (unexpected.length > 0) throw require_worktreeOperations.invalidRequest(`action='${action}' does not accept: ${unexpected.join(", ")}.`, `Fields for '${action}': ${allowed.join(", ")}.`);
|
|
187
|
+
for (const field of ["branch", "id"]) if (allowed.includes(field) && field in record) {
|
|
188
|
+
const value = record[field];
|
|
189
|
+
if (typeof value !== "string" || value.trim() === "") throw require_worktreeOperations.invalidRequest(`action='${action}' requires a nonblank '${field}'.`, `Pass a ${field}.`);
|
|
190
|
+
}
|
|
191
|
+
for (const field of [
|
|
192
|
+
"baseRef",
|
|
193
|
+
"name",
|
|
194
|
+
"task",
|
|
195
|
+
"message"
|
|
196
|
+
]) if (field in record && (typeof record[field] !== "string" || record[field].trim() === "")) throw require_worktreeOperations.invalidRequest(`action='${action}' requires a nonblank '${field}'.`, `Pass a ${field}.`);
|
|
197
|
+
for (const field of ["force", "dryRun"]) if (field in record && typeof record[field] !== "boolean") throw require_worktreeOperations.invalidRequest(`action='${action}' requires boolean '${field}'.`, `Pass true or false for ${field}.`);
|
|
198
|
+
if (action === WORKTREE_ACTIONS.send && typeof record.message !== "string") throw require_worktreeOperations.invalidRequest("action='send' requires 'message'.", "Pass the message to send.");
|
|
199
|
+
if (action === WORKTREE_ACTIONS.spawn_worktree && typeof record.branch !== "string") throw require_worktreeOperations.invalidRequest("action='spawn_worktree' requires 'branch'.", "Name the branch to create.");
|
|
200
|
+
if ((action === WORKTREE_ACTIONS.close_worktree || action === WORKTREE_ACTIONS.status || action === WORKTREE_ACTIONS.merge || action === WORKTREE_ACTIONS.send || action === WORKTREE_ACTIONS.messages) && typeof record.id !== "string") throw require_worktreeOperations.invalidRequest(`action='${action}' requires 'id'.`, "Call list to see the current ids.");
|
|
201
|
+
return record;
|
|
202
|
+
}
|
|
203
|
+
function describe(record, sessionId) {
|
|
204
|
+
const relationship = record.parentSessionId === sessionId ? "parent" : record.sessionId === sessionId ? "child" : "other session";
|
|
205
|
+
return `${record.id} ${record.branch} ${record.status} (${relationship}) ${record.path}`;
|
|
206
|
+
}
|
|
207
|
+
function text(...lines) {
|
|
208
|
+
return [{
|
|
209
|
+
type: "text",
|
|
210
|
+
text: lines.join("\n")
|
|
211
|
+
}];
|
|
212
|
+
}
|
|
213
|
+
async function executeRunWorktreeTool(params, operations, context, options = {}) {
|
|
214
|
+
switch (params.action) {
|
|
215
|
+
case WORKTREE_ACTIONS.spawn_worktree: {
|
|
216
|
+
const record = await operations.spawn(context, {
|
|
217
|
+
branch: params.branch,
|
|
218
|
+
...params.baseRef === void 0 ? {} : { baseRef: params.baseRef },
|
|
219
|
+
...params.name === void 0 ? {} : { name: params.name },
|
|
220
|
+
...params.task === void 0 ? {} : { task: params.task }
|
|
221
|
+
}, options);
|
|
222
|
+
return {
|
|
223
|
+
content: text(`Worktree ${record.id} created on ${record.branch} from ${record.baseRef}.`, `Path: ${record.path}`, params.task === void 0 ? `Session ${record.sessionId} is starting; it appears nested under this one in the rail.` : `Session ${record.sessionId} is starting with its task; it appears nested under this one in the rail.`),
|
|
224
|
+
details: {
|
|
225
|
+
action: params.action,
|
|
226
|
+
records: [record]
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
case WORKTREE_ACTIONS.close_worktree: {
|
|
231
|
+
const record = await operations.close(context, params.id, params.force ?? false);
|
|
232
|
+
return {
|
|
233
|
+
content: text(`Worktree ${record.id} (${record.branch}) closed and removed.`),
|
|
234
|
+
details: {
|
|
235
|
+
action: params.action,
|
|
236
|
+
records: [record]
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
case WORKTREE_ACTIONS.list: {
|
|
241
|
+
const records = await operations.list(context);
|
|
242
|
+
return {
|
|
243
|
+
content: records.length === 0 ? text("No worktrees for this repository.") : text(`${String(records.length)} worktree(s):`, ...records.map((record) => describe(record, context.sessionId))),
|
|
244
|
+
details: {
|
|
245
|
+
action: params.action,
|
|
246
|
+
records
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
case WORKTREE_ACTIONS.status: {
|
|
251
|
+
const { record, dirtyFiles } = await operations.status(context, params.id);
|
|
252
|
+
return {
|
|
253
|
+
content: text(describe(record, context.sessionId), `Session: ${record.sessionId}`, dirtyFiles.length === 0 ? "Clean." : `${String(dirtyFiles.length)} uncommitted file(s): ${dirtyFiles.slice(0, 20).join(", ")}`),
|
|
254
|
+
details: {
|
|
255
|
+
action: params.action,
|
|
256
|
+
records: [record]
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
case WORKTREE_ACTIONS.merge: {
|
|
261
|
+
const record = await operations.merge(context, params.id, ...params.message === void 0 ? [] : [params.message]);
|
|
262
|
+
return {
|
|
263
|
+
content: text(`Merged ${record.branch} into this checkout.`),
|
|
264
|
+
details: {
|
|
265
|
+
action: params.action,
|
|
266
|
+
records: [record]
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
case WORKTREE_ACTIONS.send:
|
|
271
|
+
await operations.send(context, params.id, params.message);
|
|
272
|
+
return {
|
|
273
|
+
content: text(`Message sent to worktree ${params.id}.`),
|
|
274
|
+
details: { action: params.action }
|
|
275
|
+
};
|
|
276
|
+
case WORKTREE_ACTIONS.messages: {
|
|
277
|
+
const waiting = await operations.messages(context, params.id);
|
|
278
|
+
return {
|
|
279
|
+
content: waiting.length === 0 ? text("No messages.") : text(`${String(waiting.length)} message(s):`, ...waiting.map((entry) => `[${entry.sentAt}] ${entry.from}: ${entry.text}`)),
|
|
280
|
+
details: { action: params.action }
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
case WORKTREE_ACTIONS.prune: {
|
|
284
|
+
const dryRun = params.dryRun ?? false;
|
|
285
|
+
const plan = await operations.prune(context, dryRun);
|
|
286
|
+
return {
|
|
287
|
+
content: text(...[
|
|
288
|
+
dryRun ? "Prune plan (nothing was changed):" : "Pruned:",
|
|
289
|
+
`Remove: ${plan.remove.length === 0 ? "none" : plan.remove.map((record) => record.id).join(", ")}`,
|
|
290
|
+
`Forget: ${plan.forget.length === 0 ? "none" : plan.forget.map((record) => record.id).join(", ")}`,
|
|
291
|
+
`Kept, uncommitted work: ${plan.keptDirty.length === 0 ? "none" : plan.keptDirty.map((record) => record.id).join(", ")}`,
|
|
292
|
+
`Untracked directories, left alone: ${plan.untracked.length === 0 ? "none" : plan.untracked.join(", ")}`,
|
|
293
|
+
...plan.keptBranches.length === 0 ? [] : [`Branches kept, they hold commits: ${plan.keptBranches.join(", ")}`]
|
|
294
|
+
]),
|
|
295
|
+
details: { action: params.action }
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
//#endregion
|
|
301
|
+
Object.defineProperty(exports, "COMMAND_DESCRIPTION", {
|
|
302
|
+
enumerable: true,
|
|
303
|
+
get: function() {
|
|
304
|
+
return COMMAND_DESCRIPTION;
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
Object.defineProperty(exports, "COMMAND_NAME", {
|
|
308
|
+
enumerable: true,
|
|
309
|
+
get: function() {
|
|
310
|
+
return COMMAND_NAME;
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
Object.defineProperty(exports, "GIT_AUTH_PATH", {
|
|
314
|
+
enumerable: true,
|
|
315
|
+
get: function() {
|
|
316
|
+
return GIT_AUTH_PATH;
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
Object.defineProperty(exports, "GIT_BRANCHES_PATH", {
|
|
320
|
+
enumerable: true,
|
|
321
|
+
get: function() {
|
|
322
|
+
return GIT_BRANCHES_PATH;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
Object.defineProperty(exports, "GIT_REVIEW_FILE_PATH", {
|
|
326
|
+
enumerable: true,
|
|
327
|
+
get: function() {
|
|
328
|
+
return GIT_REVIEW_FILE_PATH;
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
Object.defineProperty(exports, "GIT_REVIEW_PATH", {
|
|
332
|
+
enumerable: true,
|
|
333
|
+
get: function() {
|
|
334
|
+
return GIT_REVIEW_PATH;
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
Object.defineProperty(exports, "GIT_SESSIONS_PATH", {
|
|
338
|
+
enumerable: true,
|
|
339
|
+
get: function() {
|
|
340
|
+
return GIT_SESSIONS_PATH;
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
Object.defineProperty(exports, "RUN_WORKTREE_DESCRIPTION", {
|
|
344
|
+
enumerable: true,
|
|
345
|
+
get: function() {
|
|
346
|
+
return RUN_WORKTREE_DESCRIPTION;
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
Object.defineProperty(exports, "RUN_WORKTREE_TOOL_NAME", {
|
|
350
|
+
enumerable: true,
|
|
351
|
+
get: function() {
|
|
352
|
+
return RUN_WORKTREE_TOOL_NAME;
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
Object.defineProperty(exports, "RunWorktreeToolSchema", {
|
|
356
|
+
enumerable: true,
|
|
357
|
+
get: function() {
|
|
358
|
+
return RunWorktreeToolSchema;
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
Object.defineProperty(exports, "executeRunWorktreeTool", {
|
|
362
|
+
enumerable: true,
|
|
363
|
+
get: function() {
|
|
364
|
+
return executeRunWorktreeTool;
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
Object.defineProperty(exports, "validateParams", {
|
|
368
|
+
enumerable: true,
|
|
369
|
+
get: function() {
|
|
370
|
+
return validateParams;
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
//# sourceMappingURL=runWorktree-BE795LxL.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runWorktree-BE795LxL.cjs","names":["Type","invalidRequest"],"sources":["../src/constants/git.ts","../src/schemas/runWorktreeTool.ts","../src/services/runWorktree/index.ts"],"sourcesContent":["export const COMMAND_NAME = 'doom-git';\nexport const COMMAND_DESCRIPTION = 'Show git worktrees owned by this session';\n/** The package API base path; the cockpit mounts it at /api/workspaces/<id>/plugins/git. */\nexport const GIT_API_BASE_PATH = 'git';\n/** Workspace-mounted routes behind the new-session dialog. */\nexport const GIT_BRANCHES_PATH = '/branches';\nexport const GIT_SESSIONS_PATH = '/sessions';\n/** Workspace-mounted: that workspace's remote auth for manual pull, push and rebase. */\nexport const GIT_AUTH_PATH = '/auth';\n/** Session-mounted: the session's change against its base, and one file's hunks. */\nexport const GIT_REVIEW_PATH = '/review';\nexport const GIT_REVIEW_FILE_PATH = '/review/file';\n","import { type Static, Type } from 'typebox';\n\n/**\n * The tool's action vocabulary.\n *\n * One tool with an action field rather than six tools, matching `subagent`:\n * the actions share a subject and are meaningless apart from it, and six\n * separate tools would spend six description budgets teaching the same nouns.\n */\nexport const WORKTREE_ACTIONS = {\n spawn_worktree: 'spawn_worktree',\n close_worktree: 'close_worktree',\n list: 'list',\n status: 'status',\n merge: 'merge',\n prune: 'prune',\n send: 'send',\n messages: 'messages',\n} as const;\n\nexport type WorktreeAction = (typeof WORKTREE_ACTIONS)[keyof typeof WORKTREE_ACTIONS];\n\n/**\n * Which fields each action accepts.\n *\n * Rejecting an unknown field is what stops a plausible-looking call from doing\n * something other than what it reads like: `close_worktree` with `branch`\n * instead of `id` would otherwise close whatever the default resolved to.\n */\nexport const WORKTREE_ACTION_FIELDS: Record<WorktreeAction, readonly string[]> = {\n spawn_worktree: ['action', 'branch', 'baseRef', 'task', 'name'],\n close_worktree: ['action', 'id', 'force'],\n list: ['action'],\n status: ['action', 'id'],\n merge: ['action', 'id', 'message'],\n prune: ['action', 'dryRun'],\n send: ['action', 'id', 'message'],\n messages: ['action', 'id'],\n};\n\nconst SpawnParams = Type.Object(\n {\n action: Type.Literal(WORKTREE_ACTIONS.spawn_worktree),\n branch: Type.String({ minLength: 1 }),\n baseRef: Type.Optional(Type.String({ minLength: 1 })),\n task: Type.Optional(Type.String({ minLength: 1 })),\n name: Type.Optional(Type.String({ minLength: 1 })),\n },\n { additionalProperties: false },\n);\n\nconst CloseParams = Type.Object(\n {\n action: Type.Literal(WORKTREE_ACTIONS.close_worktree),\n id: Type.String({ minLength: 1 }),\n force: Type.Optional(Type.Boolean()),\n },\n { additionalProperties: false },\n);\n\nconst ListParams = Type.Object({ action: Type.Literal(WORKTREE_ACTIONS.list) }, { additionalProperties: false });\n\nconst StatusParams = Type.Object(\n { action: Type.Literal(WORKTREE_ACTIONS.status), id: Type.String({ minLength: 1 }) },\n { additionalProperties: false },\n);\n\nconst MergeParams = Type.Object(\n {\n action: Type.Literal(WORKTREE_ACTIONS.merge),\n id: Type.String({ minLength: 1 }),\n message: Type.Optional(Type.String({ minLength: 1 })),\n },\n { additionalProperties: false },\n);\n\nconst PruneParams = Type.Object(\n { action: Type.Literal(WORKTREE_ACTIONS.prune), dryRun: Type.Optional(Type.Boolean()) },\n { additionalProperties: false },\n);\n\nconst SendParams = Type.Object(\n {\n action: Type.Literal(WORKTREE_ACTIONS.send),\n id: Type.String({ minLength: 1 }),\n message: Type.String({ minLength: 1 }),\n },\n { additionalProperties: false },\n);\n\nconst MessagesParams = Type.Object(\n { action: Type.Literal(WORKTREE_ACTIONS.messages), id: Type.String({ minLength: 1 }) },\n { additionalProperties: false },\n);\n\nexport const RunWorktreeParams = Type.Union([\n SpawnParams,\n CloseParams,\n ListParams,\n StatusParams,\n MergeParams,\n PruneParams,\n SendParams,\n MessagesParams,\n]);\n\n/** The actions that accept `field`, so the declared docs cannot drift from the validator. */\nfunction acceptingActions(field: string): string {\n return Object.values(WORKTREE_ACTIONS)\n .filter((action) => WORKTREE_ACTION_FIELDS[action].includes(field))\n .join(', ');\n}\n\n/**\n * The schema declared to the model.\n *\n * A flat object rather than `RunWorktreeParams` itself. A top-level union is\n * `{anyOf:[...]}` with no `properties`, and Pi's Anthropic Messages adapter\n * rebuilds tool input as `{type:'object', properties: schema.properties ?? {},\n * required: schema.required ?? []}`, so the union arrived at the model as an\n * empty object while the host went on validating calls against it. Nothing here\n * relaxes what is accepted: `validateParams` still rejects an unknown action, a\n * field the action does not take, and a missing required one.\n */\nexport const RunWorktreeToolSchema = Type.Object(\n {\n action: Type.String({\n enum: Object.values(WORKTREE_ACTIONS),\n description: 'The operation to run. Every other field is accepted only by the actions its description names.',\n }),\n branch: Type.Optional(\n Type.String({ minLength: 1, description: `New branch to create. Actions: ${acceptingActions('branch')}.` }),\n ),\n baseRef: Type.Optional(\n Type.String({\n minLength: 1,\n description: `Base ref, defaulting to the current branch. Actions: ${acceptingActions('baseRef')}.`,\n }),\n ),\n task: Type.Optional(\n Type.String({\n minLength: 1,\n description: `First message for the new session. Actions: ${acceptingActions('task')}.`,\n }),\n ),\n name: Type.Optional(\n Type.String({ minLength: 1, description: `Rail label for the worktree. Actions: ${acceptingActions('name')}.` }),\n ),\n id: Type.Optional(Type.String({ minLength: 1, description: `Worktree id. Actions: ${acceptingActions('id')}.` })),\n force: Type.Optional(\n Type.Boolean({ description: `Close even when the tree is dirty. Actions: ${acceptingActions('force')}.` }),\n ),\n message: Type.Optional(\n Type.String({\n minLength: 1,\n description: `Merge commit message, or the text to send. Actions: ${acceptingActions('message')}.`,\n }),\n ),\n dryRun: Type.Optional(\n Type.Boolean({\n description: `Report the plan without destroying anything. Actions: ${acceptingActions('dryRun')}.`,\n }),\n ),\n },\n { additionalProperties: false },\n);\n\nexport type RunWorktreeToolParams = Static<typeof RunWorktreeParams>;\n","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's remote-tracking ref, then the remote default branch), 'name' for the rail, 'task' as the first message.\n- close_worktree: stop a worktree's session, delete its checkout, and remove its generated sync storage. Requires 'id'. Refuses a dirty tree unless 'force' is true.\n- list: every worktree for this repository, with status and relationship to the calling session.\n- status: one worktree, its relationship to the calling session, 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 and their generated sync storage. 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\nFor a nested worktree session, use the record labelled 'child' in list to report to your parent. Use records labelled 'parent' to contact your own children. Other records are not communication edges.\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, sessionId: string): string {\n const relationship =\n record.parentSessionId === sessionId ? 'parent' : record.sessionId === sessionId ? 'child' : 'other session';\n return `${record.id} ${record.branch} ${record.status} (${relationship}) ${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 ...(params.task === undefined ? {} : { task: params.task }),\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 params.task === undefined\n ? `Session ${record.sessionId} is starting; it appears nested under this one in the rail.`\n : `Session ${record.sessionId} is starting with its task; 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(\n `${String(records.length)} worktree(s):`,\n ...records.map((record) => describe(record, context.sessionId)),\n ),\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, context.sessionId),\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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"}
|