@blogic-cz/agent-tools 1.5.3 → 1.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +4 -4
  2. package/dist/audit-tool/main.d.ts +3 -0
  3. package/dist/audit-tool/main.d.ts.map +1 -0
  4. package/dist/az-tool/main.d.ts +3 -0
  5. package/dist/az-tool/main.d.ts.map +1 -0
  6. package/dist/azdo-tool/main.d.ts +3 -0
  7. package/dist/azdo-tool/main.d.ts.map +1 -0
  8. package/dist/db-tool/main.d.ts +3 -0
  9. package/dist/db-tool/main.d.ts.map +1 -0
  10. package/dist/gh-tool/main.d.ts +3 -0
  11. package/dist/gh-tool/main.d.ts.map +1 -0
  12. package/dist/gh-tool/pr/core.d.ts.map +1 -1
  13. package/dist/gh-tool/workflow.d.ts.map +1 -1
  14. package/dist/k8s-tool/main.d.ts +3 -0
  15. package/dist/k8s-tool/main.d.ts.map +1 -0
  16. package/dist/logs-tool/index.d.ts +1 -19
  17. package/dist/logs-tool/index.d.ts.map +1 -1
  18. package/dist/logs-tool/main.d.ts +21 -0
  19. package/dist/logs-tool/main.d.ts.map +1 -0
  20. package/dist/observability-tool/main.d.ts +3 -0
  21. package/dist/observability-tool/main.d.ts.map +1 -0
  22. package/dist/session-tool/index.d.ts +1 -11
  23. package/dist/session-tool/index.d.ts.map +1 -1
  24. package/dist/session-tool/main.d.ts +13 -0
  25. package/dist/session-tool/main.d.ts.map +1 -0
  26. package/dist/shared/effect-version.d.ts +4 -0
  27. package/dist/shared/effect-version.d.ts.map +1 -0
  28. package/package.json +2 -2
  29. package/src/audit-tool/index.ts +3 -109
  30. package/src/audit-tool/main.ts +111 -0
  31. package/src/az-tool/index.ts +3 -151
  32. package/src/az-tool/main.ts +153 -0
  33. package/src/azdo-tool/index.ts +3 -220
  34. package/src/azdo-tool/main.ts +222 -0
  35. package/src/db-tool/index.ts +3 -260
  36. package/src/db-tool/main.ts +262 -0
  37. package/src/gh-tool/index.ts +3 -256
  38. package/src/gh-tool/main.ts +258 -0
  39. package/src/gh-tool/pr/core.ts +52 -2
  40. package/src/gh-tool/workflow.ts +1 -0
  41. package/src/k8s-tool/index.ts +3 -487
  42. package/src/k8s-tool/main.ts +489 -0
  43. package/src/logs-tool/index.ts +3 -247
  44. package/src/logs-tool/main.ts +249 -0
  45. package/src/observability-tool/index.ts +3 -34
  46. package/src/observability-tool/main.ts +36 -0
  47. package/src/session-tool/index.ts +3 -337
  48. package/src/session-tool/main.ts +339 -0
  49. package/src/shared/effect-version.ts +32 -0
@@ -1,258 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- import { Command } from "effect/unstable/cli";
3
- import { BunRuntime, BunServices } from "@effect/platform-bun";
4
- import { Effect, Layer } from "effect";
2
+ import { checkEffectVersion } from "#shared/effect-version";
5
3
 
6
- import { makeSchemaCommand, renderCauseToStderr, VERSION } from "#shared";
7
- import { AuditServiceLayer, withAudit } from "#shared/audit";
8
- import { ConfigServiceLayer } from "#config";
9
- import {
10
- issueCloseCommand,
11
- issueCommentCommand,
12
- issueCommentsCommand,
13
- issueCreateCommand,
14
- issueEditCommand,
15
- issueListCommand,
16
- issueReopenCommand,
17
- issueSnapshotBatchCommand,
18
- issueTriageCommand,
19
- issueViewCommand,
20
- } from "./issue";
21
- import {
22
- prViewCommand,
23
- prStatusCommand,
24
- prListCommand,
25
- prCreateCommand,
26
- prCloseCommand,
27
- prEditCommand,
28
- prMergeCommand,
29
- prReadyCommand,
30
- prStackCommand,
31
- prRequestReviewCommand,
32
- prThreadsCommand,
33
- prCommentsCommand,
34
- prIssueCommentsCommand,
35
- prIssueCommentsLatestCommand,
36
- prCommentCommand,
37
- prDiscussionSummaryCommand,
38
- prFeedbackCommand,
39
- prReplyCommand,
40
- prResolveCommand,
41
- prReviewCommand,
42
- prReviewsCommand,
43
- prLastHumanReviewerCommand,
44
- prSubmitReviewCommand,
45
- prChecksCommand,
46
- prChecksFailedCommand,
47
- prRerunChecksCommand,
48
- prTriggerChecksCommand,
49
- prReplyAndResolveCommand,
50
- prReviewTriageBatchCommand,
51
- prReviewTriageCommand,
52
- prWaitMergeableCommand,
53
- prWatchCommand,
54
- } from "./pr/index";
55
- import { branchRenameCommand } from "./branch";
56
- import {
57
- gistCreateCommand,
58
- gistDeleteCommand,
59
- gistEditCommand,
60
- gistListCommand,
61
- gistViewCommand,
62
- } from "./gist";
63
- import {
64
- releaseCreateCommand,
65
- releaseDeleteCommand,
66
- releaseEditCommand,
67
- releaseListCommand,
68
- releaseStatusCommand,
69
- releaseViewCommand,
70
- } from "./release";
71
- import { repoInfoCommand, repoListCommand, repoSearchCodeCommand } from "./repo";
72
- import { GitHubService } from "./service";
73
- import {
74
- workflowAnnotationsCommand,
75
- workflowCancelCommand,
76
- workflowJobLogsCommand,
77
- workflowJobsCommand,
78
- workflowListCommand,
79
- workflowLogsCommand,
80
- workflowRerunCommand,
81
- workflowRunCommand,
82
- workflowViewCommand,
83
- workflowWatchCommand,
84
- } from "./workflow";
85
-
86
- const prCommand = Command.make("pr", {}).pipe(
87
- Command.withDescription("Pull request operations (view, create, merge, reviews, checks)"),
88
- Command.withSubcommands([
89
- prViewCommand,
90
- prStatusCommand,
91
- prListCommand,
92
- prCreateCommand,
93
- prCloseCommand,
94
- prEditCommand,
95
- prMergeCommand,
96
- prReadyCommand,
97
- prStackCommand,
98
- prRequestReviewCommand,
99
- prWaitMergeableCommand,
100
- prThreadsCommand,
101
- prCommentsCommand,
102
- prReviewsCommand,
103
- prLastHumanReviewerCommand,
104
- prFeedbackCommand,
105
- prIssueCommentsCommand,
106
- prIssueCommentsLatestCommand,
107
- prCommentCommand,
108
- prDiscussionSummaryCommand,
109
- prReplyCommand,
110
- prResolveCommand,
111
- prReviewCommand,
112
- prSubmitReviewCommand,
113
- prChecksCommand,
114
- prChecksFailedCommand,
115
- prWatchCommand,
116
- prRerunChecksCommand,
117
- prTriggerChecksCommand,
118
- prReplyAndResolveCommand,
119
- prReviewTriageCommand,
120
- prReviewTriageBatchCommand,
121
- ]),
122
- );
123
-
124
- const issueCommand = Command.make("issue", {}).pipe(
125
- Command.withDescription(
126
- "Issue operations (list, view, comments, triage, snapshot-batch, create, close, reopen, comment, edit)",
127
- ),
128
- Command.withSubcommands([
129
- issueListCommand,
130
- issueViewCommand,
131
- issueCommentsCommand,
132
- issueTriageCommand,
133
- issueSnapshotBatchCommand,
134
- issueCreateCommand,
135
- issueCloseCommand,
136
- issueReopenCommand,
137
- issueCommentCommand,
138
- issueEditCommand,
139
- ]),
140
- );
141
-
142
- const branchCommand = Command.make("branch", {}).pipe(
143
- Command.withDescription("Branch operations (rename)"),
144
- Command.withSubcommands([branchRenameCommand]),
145
- );
146
-
147
- const repoCommand = Command.make("repo", {}).pipe(
148
- Command.withDescription("Repository operations"),
149
- Command.withSubcommands([repoInfoCommand, repoListCommand, repoSearchCodeCommand]),
150
- );
151
-
152
- const workflowCommand = Command.make("workflow", {}).pipe(
153
- Command.withDescription(
154
- "GitHub Actions workflow operations (run, list, view, jobs, logs, job-logs, annotations, rerun, cancel, watch)",
155
- ),
156
- Command.withSubcommands([
157
- workflowRunCommand,
158
- workflowListCommand,
159
- workflowViewCommand,
160
- workflowJobsCommand,
161
- workflowLogsCommand,
162
- workflowJobLogsCommand,
163
- workflowAnnotationsCommand,
164
- workflowRerunCommand,
165
- workflowCancelCommand,
166
- workflowWatchCommand,
167
- ]),
168
- );
169
-
170
- const releaseCommand = Command.make("release", {}).pipe(
171
- Command.withDescription("Release operations (create, list, view, edit, delete, status)"),
172
- Command.withSubcommands([
173
- releaseCreateCommand,
174
- releaseListCommand,
175
- releaseViewCommand,
176
- releaseEditCommand,
177
- releaseDeleteCommand,
178
- releaseStatusCommand,
179
- ]),
180
- );
181
-
182
- const gistCommand = Command.make("gist", {}).pipe(
183
- Command.withDescription("Gist operations (list, view, create, edit, delete)"),
184
- Command.withSubcommands([
185
- gistListCommand,
186
- gistViewCommand,
187
- gistCreateCommand,
188
- gistEditCommand,
189
- gistDeleteCommand,
190
- ]),
191
- );
192
-
193
- const commandsCommand = makeSchemaCommand(() => mainCommand);
194
-
195
- const mainCommand = Command.make("gh-tool", {}).pipe(
196
- Command.withDescription(
197
- `GitHub CLI Tool for Coding Agents
198
-
199
- Wraps the GitHub CLI (gh) with structured output for AI agents.
200
- Supports PR management, issue management, reviews, CI checks, and repo info.
201
-
202
- WORKFLOW FOR AI AGENTS:
203
- 1. Use 'pr view' to inspect current PR
204
- 2. Use 'pr discussion-summary' for overview (counts + latest discussion comment)
205
- 3. Use 'pr threads' and 'pr issue-comments-latest --author <username> --body-contains "Review"' for review context
206
- 4. Use 'pr reply', 'pr comment' and 'pr resolve' to handle feedback
207
- 4b. Use 'pr review --event request-changes|approve|comment --confirm' to post a verdict, or 'pr submit-review' for a pending one
208
- 5. Use 'pr checks' to monitor CI status; 'pr trigger-checks --workflow <file.yml>' when zero checks were reported
209
- 6. Use 'pr merge' to merge (dry-run by default)
210
- 7. Use 'issue list' to list open/closed issues
211
- 8. Use 'issue triage --issue N --verbosity full' to inspect one issue in one call
212
- 9. Use 'issue comments --issue N' to read issue discussion comments separately
213
- 10. Use 'issue close --issue N --comment "reason"' to close issues
214
- 11. Use 'issue comment --issue N --body "text"' to comment on issues
215
- 12. Use 'repo info' to get repository metadata
216
- 13. Use 'workflow run' to dispatch workflow_dispatch workflows
217
- 14. Use 'workflow list' to list recent workflow runs
218
- 15. Use 'workflow view --run N' to inspect a specific run with jobs/steps
219
- 16. Use 'workflow logs --run N' to get logs (failed jobs by default)
220
- 17. Use 'workflow job-logs --run N --job "build-web-app"' to get clean parsed logs for a specific job
221
- 18. Use 'workflow annotations --run N' to list CI annotations (errors, warnings, notices)
222
- 19. Use 'workflow watch --run N' to watch until completion
223
- 20. Use 'release status' to inspect latest release + repository context
224
- 21. Use 'release create --tag vX.Y.Z --generate-notes' to publish a release
225
- 22. Use 'release edit/view/list/delete' to maintain existing releases
226
- 23. Use 'branch rename --old-name X --new-name Y --confirm' to rename a branch
227
- 24. Use 'gist list/view' to read gists and 'gist create --files a.ts --desc "..."' to share snippets`,
228
- ),
229
- Command.withSubcommands([
230
- prCommand,
231
- issueCommand,
232
- repoCommand,
233
- branchCommand,
234
- workflowCommand,
235
- releaseCommand,
236
- gistCommand,
237
- commandsCommand,
238
- ]),
239
- );
240
-
241
- const cli = Command.run(mainCommand, {
242
- version: VERSION,
243
- });
244
-
245
- const MainLayer = GitHubService.layer.pipe(
246
- Layer.provideMerge(BunServices.layer),
247
- Layer.provideMerge(AuditServiceLayer),
248
- Layer.provideMerge(ConfigServiceLayer),
249
- );
250
-
251
- const program = withAudit("gh", cli).pipe(
252
- Effect.provide(MainLayer),
253
- Effect.tapCause(renderCauseToStderr),
254
- );
255
-
256
- BunRuntime.runMain(program, {
257
- disableErrorReporting: true,
258
- });
4
+ if (await checkEffectVersion()) await import("./main");
5
+ else process.exitCode = 1;
@@ -0,0 +1,258 @@
1
+ #!/usr/bin/env bun
2
+ import { Command } from "effect/unstable/cli";
3
+ import { BunRuntime, BunServices } from "@effect/platform-bun";
4
+ import { Effect, Layer } from "effect";
5
+
6
+ import { makeSchemaCommand, renderCauseToStderr, VERSION } from "#shared";
7
+ import { AuditServiceLayer, withAudit } from "#shared/audit";
8
+ import { ConfigServiceLayer } from "#config";
9
+ import {
10
+ issueCloseCommand,
11
+ issueCommentCommand,
12
+ issueCommentsCommand,
13
+ issueCreateCommand,
14
+ issueEditCommand,
15
+ issueListCommand,
16
+ issueReopenCommand,
17
+ issueSnapshotBatchCommand,
18
+ issueTriageCommand,
19
+ issueViewCommand,
20
+ } from "./issue";
21
+ import {
22
+ prViewCommand,
23
+ prStatusCommand,
24
+ prListCommand,
25
+ prCreateCommand,
26
+ prCloseCommand,
27
+ prEditCommand,
28
+ prMergeCommand,
29
+ prReadyCommand,
30
+ prStackCommand,
31
+ prRequestReviewCommand,
32
+ prThreadsCommand,
33
+ prCommentsCommand,
34
+ prIssueCommentsCommand,
35
+ prIssueCommentsLatestCommand,
36
+ prCommentCommand,
37
+ prDiscussionSummaryCommand,
38
+ prFeedbackCommand,
39
+ prReplyCommand,
40
+ prResolveCommand,
41
+ prReviewCommand,
42
+ prReviewsCommand,
43
+ prLastHumanReviewerCommand,
44
+ prSubmitReviewCommand,
45
+ prChecksCommand,
46
+ prChecksFailedCommand,
47
+ prRerunChecksCommand,
48
+ prTriggerChecksCommand,
49
+ prReplyAndResolveCommand,
50
+ prReviewTriageBatchCommand,
51
+ prReviewTriageCommand,
52
+ prWaitMergeableCommand,
53
+ prWatchCommand,
54
+ } from "./pr/index";
55
+ import { branchRenameCommand } from "./branch";
56
+ import {
57
+ gistCreateCommand,
58
+ gistDeleteCommand,
59
+ gistEditCommand,
60
+ gistListCommand,
61
+ gistViewCommand,
62
+ } from "./gist";
63
+ import {
64
+ releaseCreateCommand,
65
+ releaseDeleteCommand,
66
+ releaseEditCommand,
67
+ releaseListCommand,
68
+ releaseStatusCommand,
69
+ releaseViewCommand,
70
+ } from "./release";
71
+ import { repoInfoCommand, repoListCommand, repoSearchCodeCommand } from "./repo";
72
+ import { GitHubService } from "./service";
73
+ import {
74
+ workflowAnnotationsCommand,
75
+ workflowCancelCommand,
76
+ workflowJobLogsCommand,
77
+ workflowJobsCommand,
78
+ workflowListCommand,
79
+ workflowLogsCommand,
80
+ workflowRerunCommand,
81
+ workflowRunCommand,
82
+ workflowViewCommand,
83
+ workflowWatchCommand,
84
+ } from "./workflow";
85
+
86
+ const prCommand = Command.make("pr", {}).pipe(
87
+ Command.withDescription("Pull request operations (view, create, merge, reviews, checks)"),
88
+ Command.withSubcommands([
89
+ prViewCommand,
90
+ prStatusCommand,
91
+ prListCommand,
92
+ prCreateCommand,
93
+ prCloseCommand,
94
+ prEditCommand,
95
+ prMergeCommand,
96
+ prReadyCommand,
97
+ prStackCommand,
98
+ prRequestReviewCommand,
99
+ prWaitMergeableCommand,
100
+ prThreadsCommand,
101
+ prCommentsCommand,
102
+ prReviewsCommand,
103
+ prLastHumanReviewerCommand,
104
+ prFeedbackCommand,
105
+ prIssueCommentsCommand,
106
+ prIssueCommentsLatestCommand,
107
+ prCommentCommand,
108
+ prDiscussionSummaryCommand,
109
+ prReplyCommand,
110
+ prResolveCommand,
111
+ prReviewCommand,
112
+ prSubmitReviewCommand,
113
+ prChecksCommand,
114
+ prChecksFailedCommand,
115
+ prWatchCommand,
116
+ prRerunChecksCommand,
117
+ prTriggerChecksCommand,
118
+ prReplyAndResolveCommand,
119
+ prReviewTriageCommand,
120
+ prReviewTriageBatchCommand,
121
+ ]),
122
+ );
123
+
124
+ const issueCommand = Command.make("issue", {}).pipe(
125
+ Command.withDescription(
126
+ "Issue operations (list, view, comments, triage, snapshot-batch, create, close, reopen, comment, edit)",
127
+ ),
128
+ Command.withSubcommands([
129
+ issueListCommand,
130
+ issueViewCommand,
131
+ issueCommentsCommand,
132
+ issueTriageCommand,
133
+ issueSnapshotBatchCommand,
134
+ issueCreateCommand,
135
+ issueCloseCommand,
136
+ issueReopenCommand,
137
+ issueCommentCommand,
138
+ issueEditCommand,
139
+ ]),
140
+ );
141
+
142
+ const branchCommand = Command.make("branch", {}).pipe(
143
+ Command.withDescription("Branch operations (rename)"),
144
+ Command.withSubcommands([branchRenameCommand]),
145
+ );
146
+
147
+ const repoCommand = Command.make("repo", {}).pipe(
148
+ Command.withDescription("Repository operations"),
149
+ Command.withSubcommands([repoInfoCommand, repoListCommand, repoSearchCodeCommand]),
150
+ );
151
+
152
+ const workflowCommand = Command.make("workflow", {}).pipe(
153
+ Command.withDescription(
154
+ "GitHub Actions workflow operations (run, list, view, jobs, logs, job-logs, annotations, rerun, cancel, watch)",
155
+ ),
156
+ Command.withSubcommands([
157
+ workflowRunCommand,
158
+ workflowListCommand,
159
+ workflowViewCommand,
160
+ workflowJobsCommand,
161
+ workflowLogsCommand,
162
+ workflowJobLogsCommand,
163
+ workflowAnnotationsCommand,
164
+ workflowRerunCommand,
165
+ workflowCancelCommand,
166
+ workflowWatchCommand,
167
+ ]),
168
+ );
169
+
170
+ const releaseCommand = Command.make("release", {}).pipe(
171
+ Command.withDescription("Release operations (create, list, view, edit, delete, status)"),
172
+ Command.withSubcommands([
173
+ releaseCreateCommand,
174
+ releaseListCommand,
175
+ releaseViewCommand,
176
+ releaseEditCommand,
177
+ releaseDeleteCommand,
178
+ releaseStatusCommand,
179
+ ]),
180
+ );
181
+
182
+ const gistCommand = Command.make("gist", {}).pipe(
183
+ Command.withDescription("Gist operations (list, view, create, edit, delete)"),
184
+ Command.withSubcommands([
185
+ gistListCommand,
186
+ gistViewCommand,
187
+ gistCreateCommand,
188
+ gistEditCommand,
189
+ gistDeleteCommand,
190
+ ]),
191
+ );
192
+
193
+ const commandsCommand = makeSchemaCommand(() => mainCommand);
194
+
195
+ const mainCommand = Command.make("gh-tool", {}).pipe(
196
+ Command.withDescription(
197
+ `GitHub CLI Tool for Coding Agents
198
+
199
+ Wraps the GitHub CLI (gh) with structured output for AI agents.
200
+ Supports PR management, issue management, reviews, CI checks, and repo info.
201
+
202
+ WORKFLOW FOR AI AGENTS:
203
+ 1. Use 'pr view' to inspect current PR
204
+ 2. Use 'pr discussion-summary' for overview (counts + latest discussion comment)
205
+ 3. Use 'pr threads' and 'pr issue-comments-latest --author <username> --body-contains "Review"' for review context
206
+ 4. Use 'pr reply', 'pr comment' and 'pr resolve' to handle feedback
207
+ 4b. Use 'pr review --event request-changes|approve|comment --confirm' to post a verdict, or 'pr submit-review' for a pending one
208
+ 5. Use 'pr checks' to monitor CI status; 'pr trigger-checks --workflow <file.yml>' when zero checks were reported
209
+ 6. Use 'pr merge' to merge (dry-run by default)
210
+ 7. Use 'issue list' to list open/closed issues
211
+ 8. Use 'issue triage --issue N --verbosity full' to inspect one issue in one call
212
+ 9. Use 'issue comments --issue N' to read issue discussion comments separately
213
+ 10. Use 'issue close --issue N --comment "reason"' to close issues
214
+ 11. Use 'issue comment --issue N --body "text"' to comment on issues
215
+ 12. Use 'repo info' to get repository metadata
216
+ 13. Use 'workflow run' to dispatch workflow_dispatch workflows
217
+ 14. Use 'workflow list' to list recent workflow runs
218
+ 15. Use 'workflow view --run N' to inspect a specific run with jobs/steps
219
+ 16. Use 'workflow logs --run N' to get logs (failed jobs by default)
220
+ 17. Use 'workflow job-logs --run N --job "build-web-app"' to get clean parsed logs for a specific job
221
+ 18. Use 'workflow annotations --run N' to list CI annotations (errors, warnings, notices)
222
+ 19. Use 'workflow watch --run N' to watch until completion
223
+ 20. Use 'release status' to inspect latest release + repository context
224
+ 21. Use 'release create --tag vX.Y.Z --generate-notes' to publish a release
225
+ 22. Use 'release edit/view/list/delete' to maintain existing releases
226
+ 23. Use 'branch rename --old-name X --new-name Y --confirm' to rename a branch
227
+ 24. Use 'gist list/view' to read gists and 'gist create --files a.ts --desc "..."' to share snippets`,
228
+ ),
229
+ Command.withSubcommands([
230
+ prCommand,
231
+ issueCommand,
232
+ repoCommand,
233
+ branchCommand,
234
+ workflowCommand,
235
+ releaseCommand,
236
+ gistCommand,
237
+ commandsCommand,
238
+ ]),
239
+ );
240
+
241
+ const cli = Command.run(mainCommand, {
242
+ version: VERSION,
243
+ });
244
+
245
+ const MainLayer = GitHubService.layer.pipe(
246
+ Layer.provideMerge(BunServices.layer),
247
+ Layer.provideMerge(AuditServiceLayer),
248
+ Layer.provideMerge(ConfigServiceLayer),
249
+ );
250
+
251
+ const program = withAudit("gh", cli).pipe(
252
+ Effect.provide(MainLayer),
253
+ Effect.tapCause(renderCauseToStderr),
254
+ );
255
+
256
+ BunRuntime.runMain(program, {
257
+ disableErrorReporting: true,
258
+ });
@@ -40,6 +40,8 @@ const CHECK_JSON_FIELDS = "name,state,bucket,link";
40
40
  const LONG_LIVED_BRANCHES = new Set(["main", "master", "develop", "staging", "production"]);
41
41
  const STABLE_SNAPSHOT_ATTEMPTS = 3;
42
42
  const GITHUB_ACTIONS_RUN_ID_RE = /github\.com\/[^/]+\/[^/]+\/actions\/runs\/(\d+)/;
43
+ const MERGE_SHA_POLL_INTERVAL_MS = 1000;
44
+ const MERGE_SHA_WAIT_SECONDS = 5;
43
45
 
44
46
  const validatePRTitle = Effect.fn("pr.validatePRTitle")(function* (title: string) {
45
47
  const gh = yield* GitHubService;
@@ -80,6 +82,52 @@ const validatePRTitle = Effect.fn("pr.validatePRTitle")(function* (title: string
80
82
  });
81
83
  });
82
84
 
85
+ const resolveMergeSha = Effect.fn("pr.resolveMergeSha")(function* (
86
+ pr: number,
87
+ knownSha: string | null,
88
+ ) {
89
+ if (knownSha !== null) {
90
+ return knownSha;
91
+ }
92
+
93
+ const gh = yield* GitHubService;
94
+ const readMergeSha = () =>
95
+ gh
96
+ .runGhJson<{ mergeCommit: { oid: string } | null }>([
97
+ "pr",
98
+ "view",
99
+ String(pr),
100
+ "--json",
101
+ "mergeCommit",
102
+ ])
103
+ .pipe(Effect.map((result) => result.mergeCommit?.oid ?? null));
104
+ const result = yield* readMergeSha().pipe(
105
+ Effect.andThen((initial) =>
106
+ pollUntilResolved({
107
+ initial,
108
+ isPending: (value) => value === null,
109
+ fetchLatest: readMergeSha,
110
+ intervalMs: MERGE_SHA_POLL_INTERVAL_MS,
111
+ budgetSeconds: MERGE_SHA_WAIT_SECONDS,
112
+ }),
113
+ ),
114
+ Effect.map((sha) => ({ sha, failed: false as const })),
115
+ Effect.catch((error) =>
116
+ Console.error(
117
+ `Warning: PR #${pr} was merged, but its merge commit SHA could not be read: ${error.message}`,
118
+ ).pipe(Effect.as({ sha: null, failed: true as const })),
119
+ ),
120
+ );
121
+
122
+ if (result.sha === null && !result.failed) {
123
+ yield* Console.error(
124
+ `Warning: PR #${pr} was merged, but its merge commit SHA is still unknown after ${MERGE_SHA_WAIT_SECONDS}s.`,
125
+ );
126
+ }
127
+
128
+ return result.sha;
129
+ });
130
+
83
131
  const buildChecksCommand = (pr: number | null, includeWatch: boolean): string =>
84
132
  `bun agent-tools-gh pr checks${pr !== null ? ` --pr ${pr}` : ""}${includeWatch ? " --watch" : ""}`;
85
133
 
@@ -1005,10 +1053,10 @@ export const mergePR = Effect.fn("pr.mergePR")(function* (opts: {
1005
1053
 
1006
1054
  const mergeArgs = ["pr", "merge", String(opts.pr), `--${opts.strategy}`];
1007
1055
 
1008
- const mergedSha = yield* gh
1056
+ const shaFromAsyncMerge = yield* gh
1009
1057
  .runGh(mergeArgs)
1010
1058
  .pipe(
1011
- Effect.map((result) => result.stdout.match(/([0-9a-f]{7,40})/)?.[1] ?? null),
1059
+ Effect.map(() => null),
1012
1060
  Effect.catchTag("GitHubCommandError", (error) =>
1013
1061
  ASYNC_MERGE_REQUIRED_RE.test(error.stderr)
1014
1062
  ? mergeViaAsyncApi({ pr: opts.pr, strategy: opts.strategy })
@@ -1092,6 +1140,8 @@ export const mergePR = Effect.fn("pr.mergePR")(function* (opts: {
1092
1140
  ),
1093
1141
  );
1094
1142
 
1143
+ const mergedSha = yield* resolveMergeSha(opts.pr, shaFromAsyncMerge);
1144
+
1095
1145
  // `gh pr merge --delete-branch` aborts its remote delete when the head branch is checked out in a
1096
1146
  // worktree; deleting the remote ref explicitly is worktree-independent. Local cleanup is separate.
1097
1147
  if (willDeleteBranch && repo && info.headRefName) {
@@ -877,6 +877,7 @@ export const workflowWatchCommand = Command.make(
877
877
  Flag.withDescription(
878
878
  "Include the raw watch progress frames (large); omitted by default — final status/conclusion/jobs are always returned",
879
879
  ),
880
+ Flag.withDefault(false),
880
881
  ),
881
882
  repo: repoOption,
882
883
  run: Flag.Int("run").pipe(Flag.withDescription("Workflow run ID to watch")),