@blogic-cz/agent-tools 0.8.18 → 0.10.0
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/package.json +1 -1
- package/src/gh-tool/branch.ts +91 -0
- package/src/gh-tool/index.ts +18 -2
- package/src/gh-tool/pr/commands.ts +39 -0
- package/src/gh-tool/pr/core.ts +22 -0
- package/src/gh-tool/pr/index.ts +1 -0
- package/src/gh-tool/types.ts +8 -0
package/package.json
CHANGED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Command, Flag } from "effect/unstable/cli";
|
|
2
|
+
import { Effect, Option } from "effect";
|
|
3
|
+
|
|
4
|
+
import { formatOption, logFormatted } from "#shared";
|
|
5
|
+
import type { BranchRenameResult } from "./types";
|
|
6
|
+
import { GitHubService } from "./service";
|
|
7
|
+
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Internal handlers
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
export const renameBranch = Effect.fn("branch.renameBranch")(function* (opts: {
|
|
13
|
+
oldName: string;
|
|
14
|
+
newName: string;
|
|
15
|
+
confirm: boolean;
|
|
16
|
+
repo: string | null;
|
|
17
|
+
}) {
|
|
18
|
+
const gh = yield* GitHubService;
|
|
19
|
+
|
|
20
|
+
if (!opts.confirm) {
|
|
21
|
+
const scope = opts.repo !== null ? ` in ${opts.repo}` : "";
|
|
22
|
+
|
|
23
|
+
const dryRun: BranchRenameResult = {
|
|
24
|
+
renamed: false,
|
|
25
|
+
oldName: opts.oldName,
|
|
26
|
+
newName: opts.newName,
|
|
27
|
+
dryRun: true,
|
|
28
|
+
message: `Dry run: would rename branch '${opts.oldName}' to '${opts.newName}'${scope}. Re-run with --confirm to execute.`,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return dryRun;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const repoInfo =
|
|
35
|
+
opts.repo !== null
|
|
36
|
+
? opts.repo
|
|
37
|
+
: yield* gh.getRepoInfo().pipe(Effect.map((r) => `${r.owner}/${r.name}`));
|
|
38
|
+
|
|
39
|
+
const args = [
|
|
40
|
+
"api",
|
|
41
|
+
`repos/${repoInfo}/branches/${encodeURIComponent(opts.oldName)}/rename`,
|
|
42
|
+
"-X",
|
|
43
|
+
"POST",
|
|
44
|
+
"-f",
|
|
45
|
+
`new_name=${opts.newName}`,
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
yield* gh.runGh(args);
|
|
49
|
+
|
|
50
|
+
const result: BranchRenameResult = {
|
|
51
|
+
renamed: true,
|
|
52
|
+
oldName: opts.oldName,
|
|
53
|
+
newName: opts.newName,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return result;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// CLI Commands
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
export const branchRenameCommand = Command.make(
|
|
64
|
+
"rename",
|
|
65
|
+
{
|
|
66
|
+
confirm: Flag.boolean("confirm").pipe(
|
|
67
|
+
Flag.withDescription("Actually rename (without this flag, only shows dry-run)"),
|
|
68
|
+
Flag.withDefault(false),
|
|
69
|
+
),
|
|
70
|
+
format: formatOption,
|
|
71
|
+
newName: Flag.string("new-name").pipe(Flag.withDescription("New branch name")),
|
|
72
|
+
oldName: Flag.string("old-name").pipe(Flag.withDescription("Current branch name to rename")),
|
|
73
|
+
repo: Flag.string("repo").pipe(
|
|
74
|
+
Flag.withDescription("Target repository (owner/name). Defaults to current repo"),
|
|
75
|
+
Flag.optional,
|
|
76
|
+
),
|
|
77
|
+
},
|
|
78
|
+
({ confirm, format, newName, oldName, repo }) =>
|
|
79
|
+
Effect.gen(function* () {
|
|
80
|
+
const result = yield* renameBranch({
|
|
81
|
+
oldName,
|
|
82
|
+
newName,
|
|
83
|
+
confirm,
|
|
84
|
+
repo: Option.getOrNull(repo),
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
yield* logFormatted(result, format);
|
|
88
|
+
}),
|
|
89
|
+
).pipe(
|
|
90
|
+
Command.withDescription("Rename a GitHub branch (dry-run by default, use --confirm to execute)"),
|
|
91
|
+
);
|
package/src/gh-tool/index.ts
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
prViewCommand,
|
|
21
21
|
prStatusCommand,
|
|
22
22
|
prCreateCommand,
|
|
23
|
+
prCloseCommand,
|
|
23
24
|
prEditCommand,
|
|
24
25
|
prMergeCommand,
|
|
25
26
|
prThreadsCommand,
|
|
@@ -37,6 +38,7 @@ import {
|
|
|
37
38
|
prReplyAndResolveCommand,
|
|
38
39
|
prReviewTriageCommand,
|
|
39
40
|
} from "./pr/index";
|
|
41
|
+
import { branchRenameCommand } from "./branch";
|
|
40
42
|
import {
|
|
41
43
|
releaseCreateCommand,
|
|
42
44
|
releaseDeleteCommand,
|
|
@@ -65,6 +67,7 @@ const prCommand = Command.make("pr", {}).pipe(
|
|
|
65
67
|
prViewCommand,
|
|
66
68
|
prStatusCommand,
|
|
67
69
|
prCreateCommand,
|
|
70
|
+
prCloseCommand,
|
|
68
71
|
prEditCommand,
|
|
69
72
|
prMergeCommand,
|
|
70
73
|
prThreadsCommand,
|
|
@@ -100,6 +103,11 @@ const issueCommand = Command.make("issue", {}).pipe(
|
|
|
100
103
|
]),
|
|
101
104
|
);
|
|
102
105
|
|
|
106
|
+
const branchCommand = Command.make("branch", {}).pipe(
|
|
107
|
+
Command.withDescription("Branch operations (rename)"),
|
|
108
|
+
Command.withSubcommands([branchRenameCommand]),
|
|
109
|
+
);
|
|
110
|
+
|
|
103
111
|
const repoCommand = Command.make("repo", {}).pipe(
|
|
104
112
|
Command.withDescription("Repository operations"),
|
|
105
113
|
Command.withSubcommands([repoInfoCommand, repoListCommand, repoSearchCodeCommand]),
|
|
@@ -162,9 +170,17 @@ WORKFLOW FOR AI AGENTS:
|
|
|
162
170
|
18. Use 'workflow watch --run N' to watch until completion
|
|
163
171
|
19. Use 'release status' to inspect latest release + repository context
|
|
164
172
|
20. Use 'release create --tag vX.Y.Z --generate-notes' to publish a release
|
|
165
|
-
21. Use 'release edit/view/list/delete' to maintain existing releases
|
|
173
|
+
21. Use 'release edit/view/list/delete' to maintain existing releases
|
|
174
|
+
22. Use 'branch rename --old-name X --new-name Y --confirm' to rename a branch`,
|
|
166
175
|
),
|
|
167
|
-
Command.withSubcommands([
|
|
176
|
+
Command.withSubcommands([
|
|
177
|
+
prCommand,
|
|
178
|
+
issueCommand,
|
|
179
|
+
repoCommand,
|
|
180
|
+
branchCommand,
|
|
181
|
+
workflowCommand,
|
|
182
|
+
releaseCommand,
|
|
183
|
+
]),
|
|
168
184
|
);
|
|
169
185
|
|
|
170
186
|
const cli = Command.run(mainCommand, {
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
} from "#gh/config";
|
|
18
18
|
|
|
19
19
|
import {
|
|
20
|
+
closePR,
|
|
20
21
|
createPR,
|
|
21
22
|
detectPRStatus,
|
|
22
23
|
editPR,
|
|
@@ -147,6 +148,44 @@ export const prEditCommand = Command.make(
|
|
|
147
148
|
}),
|
|
148
149
|
).pipe(Command.withDescription("Edit an existing PR's title, body, or other metadata"));
|
|
149
150
|
|
|
151
|
+
export const prCloseCommand = Command.make(
|
|
152
|
+
"close",
|
|
153
|
+
{
|
|
154
|
+
comment: Flag.string("comment").pipe(
|
|
155
|
+
Flag.withDescription("Comment to add when closing"),
|
|
156
|
+
Flag.optional,
|
|
157
|
+
),
|
|
158
|
+
commentFile: Flag.string("comment-file").pipe(
|
|
159
|
+
Flag.withDescription("Read close comment from a file path or '-' for stdin"),
|
|
160
|
+
Flag.optional,
|
|
161
|
+
),
|
|
162
|
+
deleteBranch: Flag.boolean("delete-branch").pipe(
|
|
163
|
+
Flag.withDescription("Delete the branch after closing"),
|
|
164
|
+
Flag.withDefault(false),
|
|
165
|
+
),
|
|
166
|
+
format: formatOption,
|
|
167
|
+
pr: Flag.integer("pr").pipe(Flag.withDescription("PR number to close")),
|
|
168
|
+
},
|
|
169
|
+
({ comment, commentFile, deleteBranch, format, pr }) =>
|
|
170
|
+
Effect.gen(function* () {
|
|
171
|
+
const resolvedComment = yield* resolveOptionalTextInput(
|
|
172
|
+
"gh-tool pr close",
|
|
173
|
+
Option.getOrNull(comment),
|
|
174
|
+
Option.getOrNull(commentFile),
|
|
175
|
+
"--comment",
|
|
176
|
+
"--comment-file",
|
|
177
|
+
"comment",
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
const result = yield* closePR({
|
|
181
|
+
comment: resolvedComment,
|
|
182
|
+
deleteBranch,
|
|
183
|
+
pr,
|
|
184
|
+
});
|
|
185
|
+
yield* logFormatted(result, format);
|
|
186
|
+
}),
|
|
187
|
+
).pipe(Command.withDescription("Close a PR with optional comment and branch deletion"));
|
|
188
|
+
|
|
150
189
|
export const prMergeCommand = Command.make(
|
|
151
190
|
"merge",
|
|
152
191
|
{
|
package/src/gh-tool/pr/core.ts
CHANGED
|
@@ -606,6 +606,28 @@ export const mergePR = Effect.fn("pr.mergePR")(function* (opts: {
|
|
|
606
606
|
return result;
|
|
607
607
|
});
|
|
608
608
|
|
|
609
|
+
export const closePR = Effect.fn("pr.closePR")(function* (opts: {
|
|
610
|
+
pr: number;
|
|
611
|
+
comment: string | null;
|
|
612
|
+
deleteBranch: boolean;
|
|
613
|
+
}) {
|
|
614
|
+
const gh = yield* GitHubService;
|
|
615
|
+
|
|
616
|
+
const args = ["pr", "close", String(opts.pr)];
|
|
617
|
+
|
|
618
|
+
if (opts.comment !== null) {
|
|
619
|
+
args.push("--comment", opts.comment);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
if (opts.deleteBranch) {
|
|
623
|
+
args.push("--delete-branch");
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
yield* gh.runGh(args);
|
|
627
|
+
|
|
628
|
+
return yield* viewPR(opts.pr);
|
|
629
|
+
});
|
|
630
|
+
|
|
609
631
|
export const editPR = Effect.fn("pr.editPR")(function* (opts: {
|
|
610
632
|
pr: number;
|
|
611
633
|
title: string | null;
|
package/src/gh-tool/pr/index.ts
CHANGED
package/src/gh-tool/types.ts
CHANGED
|
@@ -159,6 +159,14 @@ export type PRStatusNone = {
|
|
|
159
159
|
|
|
160
160
|
export type PRStatusResult = PRStatusSingle | PRStatusMultiple | PRStatusNone;
|
|
161
161
|
|
|
162
|
+
export type BranchRenameResult = {
|
|
163
|
+
renamed: boolean;
|
|
164
|
+
oldName: string;
|
|
165
|
+
newName: string;
|
|
166
|
+
dryRun?: true;
|
|
167
|
+
message?: string;
|
|
168
|
+
};
|
|
169
|
+
|
|
162
170
|
export type CheckRunAnnotation = {
|
|
163
171
|
path: string;
|
|
164
172
|
start_line: number;
|