@senad-d/branchme 0.1.6 → 0.1.8
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/.env.example +6 -2
- package/CHANGELOG.md +9 -5
- package/README.md +96 -19
- package/SECURITY.md +25 -7
- package/docs/PROJECT_DEFINITION_BRIEF.md +112 -77
- package/docs/SMOKE_TEST.md +21 -11
- package/docs/STRUCTURE.md +22 -17
- package/docs/TUI_CAPTURE.md +53 -22
- package/package.json +11 -7
- package/src/commands/branchme-command.ts +10 -1
- package/src/constants.ts +15 -0
- package/src/git-context.ts +22 -2
- package/src/git.ts +1124 -4
- package/src/github.ts +76 -27
- package/src/tools/branchme-tools.ts +340 -21
- package/src/types.ts +120 -0
- package/src/ui/branchme-panel.ts +14 -3
package/src/types.ts
CHANGED
|
@@ -20,6 +20,117 @@ export interface WorkingTreeDetails {
|
|
|
20
20
|
untracked: number;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
export type CreateWorktreeMode = "new" | "existing";
|
|
24
|
+
|
|
25
|
+
export type ListWorktreesToolInput = Record<string, never>;
|
|
26
|
+
|
|
27
|
+
export interface CreateWorktreeToolInput {
|
|
28
|
+
worktreePath: string;
|
|
29
|
+
branchName: string;
|
|
30
|
+
branchMode: CreateWorktreeMode;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface RemoveWorktreeToolInput {
|
|
34
|
+
worktreePath: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface WorktreeEntry {
|
|
38
|
+
path: string;
|
|
39
|
+
head: string | null;
|
|
40
|
+
branch: string | null;
|
|
41
|
+
detached: boolean;
|
|
42
|
+
bare: boolean;
|
|
43
|
+
locked: boolean;
|
|
44
|
+
lockReason: string | null;
|
|
45
|
+
prunable: boolean;
|
|
46
|
+
pruneReason: string | null;
|
|
47
|
+
main: boolean;
|
|
48
|
+
current: boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface VerifiedLinkedWorktreeEntry extends Omit<WorktreeEntry, "path" | "branch"> {
|
|
52
|
+
/** Exact machine-readable identity validated to require no BranchMe display transformation. */
|
|
53
|
+
path: string;
|
|
54
|
+
head: string;
|
|
55
|
+
/** Exact machine-readable identity validated to require no BranchMe display transformation. */
|
|
56
|
+
branch: string;
|
|
57
|
+
detached: false;
|
|
58
|
+
bare: false;
|
|
59
|
+
locked: false;
|
|
60
|
+
lockReason: null;
|
|
61
|
+
prunable: false;
|
|
62
|
+
pruneReason: null;
|
|
63
|
+
main: false;
|
|
64
|
+
current: false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface ListWorktreesDetails {
|
|
68
|
+
action: "list_worktrees";
|
|
69
|
+
repoRoot: string;
|
|
70
|
+
worktrees: WorktreeEntry[];
|
|
71
|
+
omitted: number;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface ReadyWorktreeHandoffDetails {
|
|
75
|
+
cwd: string;
|
|
76
|
+
branch: string;
|
|
77
|
+
head: string;
|
|
78
|
+
ready: true;
|
|
79
|
+
summary: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface RetainedBranchHandoffDetails {
|
|
83
|
+
cwd: null;
|
|
84
|
+
branch: string;
|
|
85
|
+
head: string;
|
|
86
|
+
ready: false;
|
|
87
|
+
summary: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export type WorktreeHandoffDetails = ReadyWorktreeHandoffDetails | RetainedBranchHandoffDetails;
|
|
91
|
+
|
|
92
|
+
export interface CreateWorktreeDetails {
|
|
93
|
+
action: "create_worktree";
|
|
94
|
+
repoRoot: string;
|
|
95
|
+
request: CreateWorktreeToolInput;
|
|
96
|
+
verified: {
|
|
97
|
+
before: {
|
|
98
|
+
sourcePath: string;
|
|
99
|
+
sourceBranch: string | null;
|
|
100
|
+
sourceDetached: boolean;
|
|
101
|
+
sourceHead: string;
|
|
102
|
+
canonicalWorktreePath: string;
|
|
103
|
+
branchExisted: boolean;
|
|
104
|
+
destinationRegistered: false;
|
|
105
|
+
};
|
|
106
|
+
after: {
|
|
107
|
+
worktreePresent: true;
|
|
108
|
+
worktree: VerifiedLinkedWorktreeEntry;
|
|
109
|
+
workingTree: WorkingTreeDetails;
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
handoff: ReadyWorktreeHandoffDetails;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface RemoveWorktreeDetails {
|
|
116
|
+
action: "remove_worktree";
|
|
117
|
+
repoRoot: string;
|
|
118
|
+
request: RemoveWorktreeToolInput;
|
|
119
|
+
verified: {
|
|
120
|
+
before: {
|
|
121
|
+
worktree: VerifiedLinkedWorktreeEntry;
|
|
122
|
+
workingTree: WorkingTreeDetails;
|
|
123
|
+
};
|
|
124
|
+
after: {
|
|
125
|
+
worktreePresent: false;
|
|
126
|
+
branchRetained: true;
|
|
127
|
+
branch: string;
|
|
128
|
+
head: string;
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
handoff: RetainedBranchHandoffDetails;
|
|
132
|
+
}
|
|
133
|
+
|
|
23
134
|
export interface GitFileChange {
|
|
24
135
|
status: string;
|
|
25
136
|
path: string;
|
|
@@ -67,6 +178,7 @@ export interface BranchStatusDetails {
|
|
|
67
178
|
}
|
|
68
179
|
|
|
69
180
|
export interface GitContextDetails extends BranchStatusDetails {
|
|
181
|
+
pullRequestAutofill: boolean | null;
|
|
70
182
|
workingTree: WorkingTreeDetails;
|
|
71
183
|
unstagedChanges: GitFileChangeSummary;
|
|
72
184
|
relatedPullRequest: RelatedPullRequest;
|
|
@@ -145,6 +257,14 @@ export interface PullRequestInput {
|
|
|
145
257
|
draft: boolean;
|
|
146
258
|
}
|
|
147
259
|
|
|
260
|
+
export type PullRequestInputField = keyof PullRequestInput;
|
|
261
|
+
|
|
262
|
+
export type PullRequestToolInput = Partial<PullRequestInput>;
|
|
263
|
+
|
|
264
|
+
export interface PullRequestToolDetails extends PullRequestDetails {
|
|
265
|
+
autofilledFields?: PullRequestInputField[];
|
|
266
|
+
}
|
|
267
|
+
|
|
148
268
|
export interface GitExecResult {
|
|
149
269
|
stdout: string;
|
|
150
270
|
stderr: string;
|
package/src/ui/branchme-panel.ts
CHANGED
|
@@ -24,14 +24,14 @@ type PanelCell =
|
|
|
24
24
|
preserveLeading?: boolean;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
export type BranchMePanelSection = "status" | "workflow";
|
|
27
|
+
export type BranchMePanelSection = "status" | "workflow" | "worktrees";
|
|
28
28
|
|
|
29
29
|
const NARROW_MIN_WIDTH = 24;
|
|
30
30
|
const WIDE_MIN_WIDTH = 72;
|
|
31
31
|
const MAX_PANEL_WIDTH = 96;
|
|
32
32
|
const MAX_PANEL_HEIGHT = 16;
|
|
33
33
|
const BODY_HEIGHT = 9;
|
|
34
|
-
const PANEL_SECTIONS: BranchMePanelSection[] = ["status", "workflow"];
|
|
34
|
+
const PANEL_SECTIONS: BranchMePanelSection[] = ["status", "workflow", "worktrees"];
|
|
35
35
|
const ANSI_RESET = "\u001b[0m";
|
|
36
36
|
|
|
37
37
|
function truncateVisible(value: string, width: number, ellipsis = "…", pad = false): string {
|
|
@@ -144,7 +144,7 @@ function statusDetailRow(label: string, value: string): PanelCell {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
function workflowDetailRow(tool: string, description: string): PanelCell {
|
|
147
|
-
return layoutCell(` ${tool.padEnd(
|
|
147
|
+
return layoutCell(` ${tool.padEnd(16, " ")}-> ${sanitize(description)}`);
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
function sectionTitle(section: BranchMePanelSection): string {
|
|
@@ -153,6 +153,8 @@ function sectionTitle(section: BranchMePanelSection): string {
|
|
|
153
153
|
return "STATUS";
|
|
154
154
|
case "workflow":
|
|
155
155
|
return "WORKFLOW";
|
|
156
|
+
case "worktrees":
|
|
157
|
+
return "WORKTREES";
|
|
156
158
|
}
|
|
157
159
|
}
|
|
158
160
|
|
|
@@ -178,6 +180,8 @@ function sectionFooter(section: BranchMePanelSection, data: BranchMePanelData):
|
|
|
178
180
|
return "status • current repository only • tools perform actions";
|
|
179
181
|
case "workflow":
|
|
180
182
|
return "workflow • inspect → change → fetch/pull/rebase → create → push → PR";
|
|
183
|
+
case "worktrees":
|
|
184
|
+
return "worktrees • create → handoff cwd → next session • remove retains branch";
|
|
181
185
|
}
|
|
182
186
|
}
|
|
183
187
|
|
|
@@ -204,6 +208,13 @@ function sectionRows(section: BranchMePanelSection, data: BranchMePanelData): Pa
|
|
|
204
208
|
workflowDetailRow("push_branch", "current branch"),
|
|
205
209
|
workflowDetailRow("pull_request", "after push"),
|
|
206
210
|
];
|
|
211
|
+
case "worktrees":
|
|
212
|
+
return [
|
|
213
|
+
heading("WORKTREES"),
|
|
214
|
+
workflowDetailRow("list_worktrees", "inspect inventory"),
|
|
215
|
+
workflowDetailRow("create_worktree", "ready handoff.cwd"),
|
|
216
|
+
workflowDetailRow("remove_worktree", "clean linked; branch retained"),
|
|
217
|
+
];
|
|
207
218
|
}
|
|
208
219
|
}
|
|
209
220
|
|