@build-astron-co/nimbus 0.2.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.
Files changed (313) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +628 -0
  3. package/bin/nimbus +38 -0
  4. package/package.json +80 -0
  5. package/src/__tests__/app.test.ts +76 -0
  6. package/src/__tests__/audit.test.ts +877 -0
  7. package/src/__tests__/circuit-breaker.test.ts +116 -0
  8. package/src/__tests__/cli-run.test.ts +115 -0
  9. package/src/__tests__/context-manager.test.ts +502 -0
  10. package/src/__tests__/context.test.ts +242 -0
  11. package/src/__tests__/enterprise.test.ts +401 -0
  12. package/src/__tests__/generator.test.ts +433 -0
  13. package/src/__tests__/hooks.test.ts +582 -0
  14. package/src/__tests__/init.test.ts +436 -0
  15. package/src/__tests__/intent-parser.test.ts +229 -0
  16. package/src/__tests__/llm-router.test.ts +209 -0
  17. package/src/__tests__/lsp.test.ts +293 -0
  18. package/src/__tests__/modes.test.ts +336 -0
  19. package/src/__tests__/permissions.test.ts +338 -0
  20. package/src/__tests__/serve.test.ts +275 -0
  21. package/src/__tests__/sessions.test.ts +227 -0
  22. package/src/__tests__/sharing.test.ts +288 -0
  23. package/src/__tests__/snapshots.test.ts +581 -0
  24. package/src/__tests__/state-db.test.ts +334 -0
  25. package/src/__tests__/stream-with-tools.test.ts +732 -0
  26. package/src/__tests__/subagents.test.ts +176 -0
  27. package/src/__tests__/system-prompt.test.ts +169 -0
  28. package/src/__tests__/tool-converter.test.ts +256 -0
  29. package/src/__tests__/tool-schemas.test.ts +397 -0
  30. package/src/__tests__/tools.test.ts +143 -0
  31. package/src/__tests__/version.test.ts +49 -0
  32. package/src/agent/compaction-agent.ts +227 -0
  33. package/src/agent/context-manager.ts +435 -0
  34. package/src/agent/context.ts +427 -0
  35. package/src/agent/deploy-preview.ts +426 -0
  36. package/src/agent/index.ts +68 -0
  37. package/src/agent/loop.ts +717 -0
  38. package/src/agent/modes.ts +429 -0
  39. package/src/agent/permissions.ts +466 -0
  40. package/src/agent/subagents/base.ts +116 -0
  41. package/src/agent/subagents/cost.ts +51 -0
  42. package/src/agent/subagents/explore.ts +42 -0
  43. package/src/agent/subagents/general.ts +54 -0
  44. package/src/agent/subagents/index.ts +102 -0
  45. package/src/agent/subagents/infra.ts +59 -0
  46. package/src/agent/subagents/security.ts +69 -0
  47. package/src/agent/system-prompt.ts +436 -0
  48. package/src/app.ts +122 -0
  49. package/src/audit/activity-log.ts +290 -0
  50. package/src/audit/compliance-checker.ts +540 -0
  51. package/src/audit/cost-tracker.ts +318 -0
  52. package/src/audit/index.ts +23 -0
  53. package/src/audit/security-scanner.ts +596 -0
  54. package/src/auth/guard.ts +75 -0
  55. package/src/auth/index.ts +56 -0
  56. package/src/auth/oauth.ts +455 -0
  57. package/src/auth/providers.ts +470 -0
  58. package/src/auth/sso.ts +113 -0
  59. package/src/auth/store.ts +505 -0
  60. package/src/auth/types.ts +187 -0
  61. package/src/build.ts +141 -0
  62. package/src/cli/index.ts +16 -0
  63. package/src/cli/init.ts +854 -0
  64. package/src/cli/openapi-spec.ts +356 -0
  65. package/src/cli/run.ts +237 -0
  66. package/src/cli/serve-auth.ts +80 -0
  67. package/src/cli/serve.ts +462 -0
  68. package/src/cli/web.ts +67 -0
  69. package/src/cli.ts +1417 -0
  70. package/src/clients/core-engine-client.ts +227 -0
  71. package/src/clients/enterprise-client.ts +334 -0
  72. package/src/clients/generator-client.ts +351 -0
  73. package/src/clients/git-client.ts +627 -0
  74. package/src/clients/github-client.ts +410 -0
  75. package/src/clients/helm-client.ts +504 -0
  76. package/src/clients/index.ts +80 -0
  77. package/src/clients/k8s-client.ts +497 -0
  78. package/src/clients/llm-client.ts +161 -0
  79. package/src/clients/rest-client.ts +130 -0
  80. package/src/clients/service-discovery.ts +33 -0
  81. package/src/clients/terraform-client.ts +482 -0
  82. package/src/clients/tools-client.ts +1843 -0
  83. package/src/clients/ws-client.ts +115 -0
  84. package/src/commands/analyze/index.ts +352 -0
  85. package/src/commands/apply/helm.ts +473 -0
  86. package/src/commands/apply/index.ts +213 -0
  87. package/src/commands/apply/k8s.ts +454 -0
  88. package/src/commands/apply/terraform.ts +582 -0
  89. package/src/commands/ask.ts +167 -0
  90. package/src/commands/audit/index.ts +238 -0
  91. package/src/commands/auth-cloud.ts +294 -0
  92. package/src/commands/auth-list.ts +134 -0
  93. package/src/commands/auth-profile.ts +121 -0
  94. package/src/commands/auth-status.ts +141 -0
  95. package/src/commands/aws/ec2.ts +501 -0
  96. package/src/commands/aws/iam.ts +397 -0
  97. package/src/commands/aws/index.ts +133 -0
  98. package/src/commands/aws/lambda.ts +396 -0
  99. package/src/commands/aws/rds.ts +439 -0
  100. package/src/commands/aws/s3.ts +439 -0
  101. package/src/commands/aws/vpc.ts +393 -0
  102. package/src/commands/aws-discover.ts +649 -0
  103. package/src/commands/aws-terraform.ts +805 -0
  104. package/src/commands/azure/aks.ts +376 -0
  105. package/src/commands/azure/functions.ts +253 -0
  106. package/src/commands/azure/index.ts +116 -0
  107. package/src/commands/azure/storage.ts +478 -0
  108. package/src/commands/azure/vm.ts +355 -0
  109. package/src/commands/billing/index.ts +256 -0
  110. package/src/commands/chat.ts +314 -0
  111. package/src/commands/config.ts +346 -0
  112. package/src/commands/cost/cloud-cost-estimator.ts +266 -0
  113. package/src/commands/cost/estimator.ts +79 -0
  114. package/src/commands/cost/index.ts +594 -0
  115. package/src/commands/cost/parsers/terraform.ts +273 -0
  116. package/src/commands/cost/parsers/types.ts +25 -0
  117. package/src/commands/cost/pricing/aws.ts +544 -0
  118. package/src/commands/cost/pricing/azure.ts +499 -0
  119. package/src/commands/cost/pricing/gcp.ts +396 -0
  120. package/src/commands/cost/pricing/index.ts +40 -0
  121. package/src/commands/demo.ts +250 -0
  122. package/src/commands/doctor.ts +794 -0
  123. package/src/commands/drift/index.ts +439 -0
  124. package/src/commands/explain.ts +277 -0
  125. package/src/commands/feedback.ts +389 -0
  126. package/src/commands/fix.ts +324 -0
  127. package/src/commands/fs/index.ts +402 -0
  128. package/src/commands/gcp/compute.ts +325 -0
  129. package/src/commands/gcp/functions.ts +271 -0
  130. package/src/commands/gcp/gke.ts +438 -0
  131. package/src/commands/gcp/iam.ts +344 -0
  132. package/src/commands/gcp/index.ts +129 -0
  133. package/src/commands/gcp/storage.ts +284 -0
  134. package/src/commands/generate-helm.ts +1249 -0
  135. package/src/commands/generate-k8s.ts +1560 -0
  136. package/src/commands/generate-terraform.ts +1460 -0
  137. package/src/commands/gh/index.ts +863 -0
  138. package/src/commands/git/index.ts +1343 -0
  139. package/src/commands/helm/index.ts +1126 -0
  140. package/src/commands/help.ts +539 -0
  141. package/src/commands/history.ts +142 -0
  142. package/src/commands/import.ts +868 -0
  143. package/src/commands/index.ts +367 -0
  144. package/src/commands/init.ts +1046 -0
  145. package/src/commands/k8s/index.ts +1137 -0
  146. package/src/commands/login.ts +631 -0
  147. package/src/commands/logout.ts +83 -0
  148. package/src/commands/onboarding.ts +228 -0
  149. package/src/commands/plan/display.ts +279 -0
  150. package/src/commands/plan/index.ts +599 -0
  151. package/src/commands/preview.ts +452 -0
  152. package/src/commands/questionnaire.ts +1270 -0
  153. package/src/commands/resume.ts +55 -0
  154. package/src/commands/team/index.ts +346 -0
  155. package/src/commands/template.ts +232 -0
  156. package/src/commands/tf/index.ts +1034 -0
  157. package/src/commands/upgrade.ts +550 -0
  158. package/src/commands/usage/index.ts +134 -0
  159. package/src/commands/version.ts +170 -0
  160. package/src/compat/index.ts +2 -0
  161. package/src/compat/runtime.ts +12 -0
  162. package/src/compat/sqlite.ts +107 -0
  163. package/src/config/index.ts +17 -0
  164. package/src/config/manager.ts +530 -0
  165. package/src/config/safety-policy.ts +358 -0
  166. package/src/config/schema.ts +125 -0
  167. package/src/config/types.ts +527 -0
  168. package/src/context/context-db.ts +199 -0
  169. package/src/demo/index.ts +349 -0
  170. package/src/demo/scenarios/full-journey.ts +229 -0
  171. package/src/demo/scenarios/getting-started.ts +127 -0
  172. package/src/demo/scenarios/helm-release.ts +341 -0
  173. package/src/demo/scenarios/k8s-deployment.ts +194 -0
  174. package/src/demo/scenarios/terraform-vpc.ts +170 -0
  175. package/src/demo/types.ts +92 -0
  176. package/src/engine/cost-estimator.ts +438 -0
  177. package/src/engine/diagram-generator.ts +256 -0
  178. package/src/engine/drift-detector.ts +902 -0
  179. package/src/engine/executor.ts +1035 -0
  180. package/src/engine/index.ts +76 -0
  181. package/src/engine/orchestrator.ts +636 -0
  182. package/src/engine/planner.ts +720 -0
  183. package/src/engine/safety.ts +743 -0
  184. package/src/engine/verifier.ts +770 -0
  185. package/src/enterprise/audit.ts +348 -0
  186. package/src/enterprise/auth.ts +270 -0
  187. package/src/enterprise/billing.ts +822 -0
  188. package/src/enterprise/index.ts +17 -0
  189. package/src/enterprise/teams.ts +443 -0
  190. package/src/generator/best-practices.ts +1608 -0
  191. package/src/generator/helm.ts +630 -0
  192. package/src/generator/index.ts +37 -0
  193. package/src/generator/intent-parser.ts +514 -0
  194. package/src/generator/kubernetes.ts +976 -0
  195. package/src/generator/terraform.ts +1867 -0
  196. package/src/history/index.ts +8 -0
  197. package/src/history/manager.ts +322 -0
  198. package/src/history/types.ts +34 -0
  199. package/src/hooks/config.ts +432 -0
  200. package/src/hooks/engine.ts +391 -0
  201. package/src/hooks/index.ts +4 -0
  202. package/src/llm/auth-bridge.ts +198 -0
  203. package/src/llm/circuit-breaker.ts +140 -0
  204. package/src/llm/config-loader.ts +201 -0
  205. package/src/llm/cost-calculator.ts +171 -0
  206. package/src/llm/index.ts +8 -0
  207. package/src/llm/model-aliases.ts +115 -0
  208. package/src/llm/provider-registry.ts +63 -0
  209. package/src/llm/providers/anthropic.ts +433 -0
  210. package/src/llm/providers/bedrock.ts +477 -0
  211. package/src/llm/providers/google.ts +405 -0
  212. package/src/llm/providers/ollama.ts +767 -0
  213. package/src/llm/providers/openai-compatible.ts +340 -0
  214. package/src/llm/providers/openai.ts +328 -0
  215. package/src/llm/providers/openrouter.ts +338 -0
  216. package/src/llm/router.ts +1035 -0
  217. package/src/llm/types.ts +232 -0
  218. package/src/lsp/client.ts +298 -0
  219. package/src/lsp/languages.ts +116 -0
  220. package/src/lsp/manager.ts +278 -0
  221. package/src/mcp/client.ts +402 -0
  222. package/src/mcp/index.ts +5 -0
  223. package/src/mcp/manager.ts +133 -0
  224. package/src/nimbus.ts +214 -0
  225. package/src/plugins/index.ts +27 -0
  226. package/src/plugins/loader.ts +334 -0
  227. package/src/plugins/manager.ts +376 -0
  228. package/src/plugins/types.ts +284 -0
  229. package/src/scanners/cicd-scanner.ts +258 -0
  230. package/src/scanners/cloud-scanner.ts +466 -0
  231. package/src/scanners/framework-scanner.ts +469 -0
  232. package/src/scanners/iac-scanner.ts +388 -0
  233. package/src/scanners/index.ts +539 -0
  234. package/src/scanners/language-scanner.ts +276 -0
  235. package/src/scanners/package-manager-scanner.ts +277 -0
  236. package/src/scanners/types.ts +172 -0
  237. package/src/sessions/manager.ts +365 -0
  238. package/src/sessions/types.ts +44 -0
  239. package/src/sharing/sync.ts +296 -0
  240. package/src/sharing/viewer.ts +97 -0
  241. package/src/snapshots/index.ts +2 -0
  242. package/src/snapshots/manager.ts +530 -0
  243. package/src/state/artifacts.ts +147 -0
  244. package/src/state/audit.ts +137 -0
  245. package/src/state/billing.ts +240 -0
  246. package/src/state/checkpoints.ts +117 -0
  247. package/src/state/config.ts +67 -0
  248. package/src/state/conversations.ts +14 -0
  249. package/src/state/credentials.ts +154 -0
  250. package/src/state/db.ts +58 -0
  251. package/src/state/index.ts +26 -0
  252. package/src/state/messages.ts +115 -0
  253. package/src/state/projects.ts +123 -0
  254. package/src/state/schema.ts +236 -0
  255. package/src/state/sessions.ts +147 -0
  256. package/src/state/teams.ts +200 -0
  257. package/src/telemetry.ts +108 -0
  258. package/src/tools/aws-ops.ts +952 -0
  259. package/src/tools/azure-ops.ts +579 -0
  260. package/src/tools/file-ops.ts +593 -0
  261. package/src/tools/gcp-ops.ts +625 -0
  262. package/src/tools/git-ops.ts +773 -0
  263. package/src/tools/github-ops.ts +799 -0
  264. package/src/tools/helm-ops.ts +943 -0
  265. package/src/tools/index.ts +17 -0
  266. package/src/tools/k8s-ops.ts +819 -0
  267. package/src/tools/schemas/converter.ts +184 -0
  268. package/src/tools/schemas/devops.ts +612 -0
  269. package/src/tools/schemas/index.ts +73 -0
  270. package/src/tools/schemas/standard.ts +1144 -0
  271. package/src/tools/schemas/types.ts +705 -0
  272. package/src/tools/terraform-ops.ts +862 -0
  273. package/src/types/ambient.d.ts +193 -0
  274. package/src/types/config.ts +83 -0
  275. package/src/types/drift.ts +116 -0
  276. package/src/types/enterprise.ts +335 -0
  277. package/src/types/index.ts +20 -0
  278. package/src/types/plan.ts +44 -0
  279. package/src/types/request.ts +65 -0
  280. package/src/types/response.ts +54 -0
  281. package/src/types/service.ts +51 -0
  282. package/src/ui/App.tsx +997 -0
  283. package/src/ui/DeployPreview.tsx +169 -0
  284. package/src/ui/Header.tsx +68 -0
  285. package/src/ui/InputBox.tsx +350 -0
  286. package/src/ui/MessageList.tsx +585 -0
  287. package/src/ui/PermissionPrompt.tsx +151 -0
  288. package/src/ui/StatusBar.tsx +158 -0
  289. package/src/ui/ToolCallDisplay.tsx +409 -0
  290. package/src/ui/chat-ui.ts +853 -0
  291. package/src/ui/index.ts +33 -0
  292. package/src/ui/ink/index.ts +711 -0
  293. package/src/ui/streaming.ts +176 -0
  294. package/src/ui/types.ts +57 -0
  295. package/src/utils/analytics.ts +72 -0
  296. package/src/utils/cost-warning.ts +27 -0
  297. package/src/utils/env.ts +46 -0
  298. package/src/utils/errors.ts +69 -0
  299. package/src/utils/event-bus.ts +38 -0
  300. package/src/utils/index.ts +24 -0
  301. package/src/utils/logger.ts +171 -0
  302. package/src/utils/rate-limiter.ts +121 -0
  303. package/src/utils/service-auth.ts +49 -0
  304. package/src/utils/validation.ts +53 -0
  305. package/src/version.ts +4 -0
  306. package/src/watcher/index.ts +163 -0
  307. package/src/wizard/approval.ts +383 -0
  308. package/src/wizard/index.ts +25 -0
  309. package/src/wizard/prompts.ts +338 -0
  310. package/src/wizard/types.ts +171 -0
  311. package/src/wizard/ui.ts +556 -0
  312. package/src/wizard/wizard.ts +304 -0
  313. package/tsconfig.json +24 -0
@@ -0,0 +1,799 @@
1
+ /**
2
+ * GitHub Operations — Embedded tool (stripped HTTP wrappers)
3
+ *
4
+ * Copied from services/github-tools-service/src/github/operations.ts
5
+ * Types inlined from services/github-tools-service/src/github/types.ts
6
+ * Provides direct GitHub API operations for the embedded CLI binary.
7
+ */
8
+
9
+ import { Octokit } from '@octokit/rest';
10
+ import { logger } from '../utils';
11
+
12
+ // ==========================================
13
+ // Inlined Types (from github-tools-service/src/github/types.ts)
14
+ // ==========================================
15
+
16
+ export interface PullRequest {
17
+ id: number;
18
+ number: number;
19
+ title: string;
20
+ body: string | null;
21
+ state: 'open' | 'closed';
22
+ html_url: string;
23
+ user: { login: string; avatar_url: string };
24
+ head: { ref: string; sha: string };
25
+ base: { ref: string };
26
+ created_at: string;
27
+ updated_at: string;
28
+ merged_at: string | null;
29
+ draft: boolean;
30
+ mergeable: boolean | null;
31
+ mergeable_state: string;
32
+ }
33
+
34
+ export interface Issue {
35
+ id: number;
36
+ number: number;
37
+ title: string;
38
+ body: string | null;
39
+ state: 'open' | 'closed';
40
+ html_url: string;
41
+ user: { login: string; avatar_url: string };
42
+ labels: Array<{ name: string; color: string }>;
43
+ assignees: Array<{ login: string }>;
44
+ created_at: string;
45
+ updated_at: string;
46
+ closed_at: string | null;
47
+ }
48
+
49
+ export interface Repository {
50
+ id: number;
51
+ name: string;
52
+ full_name: string;
53
+ description: string | null;
54
+ html_url: string;
55
+ private: boolean;
56
+ owner: { login: string; avatar_url: string };
57
+ default_branch: string;
58
+ created_at: string;
59
+ updated_at: string;
60
+ pushed_at: string;
61
+ language: string | null;
62
+ stargazers_count: number;
63
+ forks_count: number;
64
+ }
65
+
66
+ export interface Branch {
67
+ name: string;
68
+ commit: { sha: string; url: string };
69
+ protected: boolean;
70
+ }
71
+
72
+ export interface IssueComment {
73
+ id: number;
74
+ body: string;
75
+ user: { login: string; avatar_url: string };
76
+ html_url: string;
77
+ created_at: string;
78
+ updated_at: string;
79
+ }
80
+
81
+ export interface CreatePRParams {
82
+ title: string;
83
+ head: string;
84
+ base: string;
85
+ body?: string;
86
+ draft?: boolean;
87
+ }
88
+
89
+ export interface CreateIssueParams {
90
+ title: string;
91
+ body?: string;
92
+ labels?: string[];
93
+ assignees?: string[];
94
+ }
95
+
96
+ export interface MergeParams {
97
+ commit_title?: string;
98
+ commit_message?: string;
99
+ merge_method?: 'merge' | 'squash' | 'rebase';
100
+ }
101
+
102
+ export interface PRReview {
103
+ id: number;
104
+ node_id: string;
105
+ user: { login: string; id: number };
106
+ body: string;
107
+ state: string;
108
+ html_url: string;
109
+ submitted_at: string;
110
+ }
111
+
112
+ export interface WorkflowRunOptions {
113
+ workflowId?: string | number;
114
+ branch?: string;
115
+ event?: string;
116
+ status?: 'queued' | 'in_progress' | 'completed' | 'waiting';
117
+ perPage?: number;
118
+ }
119
+
120
+ export interface WorkflowRun {
121
+ id: number;
122
+ name: string;
123
+ head_branch: string;
124
+ head_sha: string;
125
+ status: string;
126
+ conclusion: string | null;
127
+ workflow_id: number;
128
+ url: string;
129
+ html_url: string;
130
+ created_at: string;
131
+ updated_at: string;
132
+ run_number: number;
133
+ event: string;
134
+ }
135
+
136
+ export interface Workflow {
137
+ id: number;
138
+ name: string;
139
+ path: string;
140
+ state: string;
141
+ url: string;
142
+ html_url: string;
143
+ badge_url: string;
144
+ created_at: string;
145
+ updated_at: string;
146
+ }
147
+
148
+ export interface ReleaseOptions {
149
+ tagName: string;
150
+ targetCommitish?: string;
151
+ name?: string;
152
+ body?: string;
153
+ draft?: boolean;
154
+ prerelease?: boolean;
155
+ generateReleaseNotes?: boolean;
156
+ }
157
+
158
+ export interface Release {
159
+ id: number;
160
+ tag_name: string;
161
+ target_commitish: string;
162
+ name: string;
163
+ body: string;
164
+ draft: boolean;
165
+ prerelease: boolean;
166
+ created_at: string;
167
+ published_at: string;
168
+ html_url: string;
169
+ assets: ReleaseAsset[];
170
+ }
171
+
172
+ export interface ReleaseAsset {
173
+ id: number;
174
+ name: string;
175
+ content_type: string;
176
+ size: number;
177
+ download_count: number;
178
+ browser_download_url: string;
179
+ }
180
+
181
+ // ==========================================
182
+ // GitHubOperations Class
183
+ // ==========================================
184
+
185
+ /**
186
+ * GitHubOperations class provides methods for interacting with GitHub API
187
+ */
188
+ export class GitHubOperations {
189
+ private octokit: Octokit;
190
+
191
+ constructor(token: string) {
192
+ this.octokit = new Octokit({ auth: token });
193
+ }
194
+
195
+ // ==========================================
196
+ // Pull Request Operations
197
+ // ==========================================
198
+
199
+ /**
200
+ * List pull requests for a repository
201
+ */
202
+ async listPRs(
203
+ owner: string,
204
+ repo: string,
205
+ state: 'open' | 'closed' | 'all' = 'open',
206
+ perPage = 30
207
+ ): Promise<PullRequest[]> {
208
+ logger.info(`Listing PRs for ${owner}/${repo}`, { state, perPage });
209
+
210
+ const { data } = await this.octokit.pulls.list({
211
+ owner,
212
+ repo,
213
+ state,
214
+ per_page: perPage,
215
+ });
216
+
217
+ return data as unknown as PullRequest[];
218
+ }
219
+
220
+ /**
221
+ * Get a single pull request
222
+ */
223
+ async getPR(owner: string, repo: string, pullNumber: number): Promise<PullRequest> {
224
+ logger.info(`Getting PR #${pullNumber} for ${owner}/${repo}`);
225
+
226
+ const { data } = await this.octokit.pulls.get({
227
+ owner,
228
+ repo,
229
+ pull_number: pullNumber,
230
+ });
231
+
232
+ return data as unknown as PullRequest;
233
+ }
234
+
235
+ /**
236
+ * Create a pull request
237
+ */
238
+ async createPR(owner: string, repo: string, params: CreatePRParams): Promise<PullRequest> {
239
+ logger.info(`Creating PR in ${owner}/${repo}`, { title: params.title });
240
+
241
+ const { data } = await this.octokit.pulls.create({
242
+ owner,
243
+ repo,
244
+ title: params.title,
245
+ head: params.head,
246
+ base: params.base,
247
+ body: params.body,
248
+ draft: params.draft,
249
+ });
250
+
251
+ return data as unknown as PullRequest;
252
+ }
253
+
254
+ /**
255
+ * Merge a pull request
256
+ */
257
+ async mergePR(
258
+ owner: string,
259
+ repo: string,
260
+ pullNumber: number,
261
+ params: MergeParams = {}
262
+ ): Promise<{ sha: string; merged: boolean; message: string }> {
263
+ logger.info(`Merging PR #${pullNumber} in ${owner}/${repo}`);
264
+
265
+ const { data } = await this.octokit.pulls.merge({
266
+ owner,
267
+ repo,
268
+ pull_number: pullNumber,
269
+ commit_title: params.commit_title,
270
+ commit_message: params.commit_message,
271
+ merge_method: params.merge_method || 'merge',
272
+ });
273
+
274
+ return data;
275
+ }
276
+
277
+ /**
278
+ * Close a pull request without merging
279
+ */
280
+ async closePR(owner: string, repo: string, pullNumber: number): Promise<PullRequest> {
281
+ logger.info(`Closing PR #${pullNumber} in ${owner}/${repo}`);
282
+
283
+ const { data } = await this.octokit.pulls.update({
284
+ owner,
285
+ repo,
286
+ pull_number: pullNumber,
287
+ state: 'closed',
288
+ });
289
+
290
+ return data as unknown as PullRequest;
291
+ }
292
+
293
+ /**
294
+ * Create a review on a pull request
295
+ */
296
+ async createPRReview(
297
+ owner: string,
298
+ repo: string,
299
+ pullNumber: number,
300
+ event: 'APPROVE' | 'REQUEST_CHANGES' | 'COMMENT',
301
+ body?: string
302
+ ): Promise<PRReview> {
303
+ logger.info(`Creating review on PR #${pullNumber} in ${owner}/${repo}`, { event });
304
+
305
+ const params: any = {
306
+ owner,
307
+ repo,
308
+ pull_number: pullNumber,
309
+ event,
310
+ };
311
+
312
+ if (body) {
313
+ params.body = body;
314
+ }
315
+
316
+ const { data } = await this.octokit.pulls.createReview(params);
317
+
318
+ return data as unknown as PRReview;
319
+ }
320
+
321
+ // ==========================================
322
+ // Issue Operations
323
+ // ==========================================
324
+
325
+ /**
326
+ * List issues for a repository
327
+ */
328
+ async listIssues(
329
+ owner: string,
330
+ repo: string,
331
+ state: 'open' | 'closed' | 'all' = 'open',
332
+ perPage = 30
333
+ ): Promise<Issue[]> {
334
+ logger.info(`Listing issues for ${owner}/${repo}`, { state, perPage });
335
+
336
+ const { data } = await this.octokit.issues.listForRepo({
337
+ owner,
338
+ repo,
339
+ state,
340
+ per_page: perPage,
341
+ });
342
+
343
+ // Filter out pull requests (issues endpoint returns both)
344
+ const issues = data.filter((item: any) => !item.pull_request);
345
+
346
+ return issues as unknown as Issue[];
347
+ }
348
+
349
+ /**
350
+ * Get a single issue
351
+ */
352
+ async getIssue(owner: string, repo: string, issueNumber: number): Promise<Issue> {
353
+ logger.info(`Getting issue #${issueNumber} for ${owner}/${repo}`);
354
+
355
+ const { data } = await this.octokit.issues.get({
356
+ owner,
357
+ repo,
358
+ issue_number: issueNumber,
359
+ });
360
+
361
+ return data as unknown as Issue;
362
+ }
363
+
364
+ /**
365
+ * Create an issue
366
+ */
367
+ async createIssue(owner: string, repo: string, params: CreateIssueParams): Promise<Issue> {
368
+ logger.info(`Creating issue in ${owner}/${repo}`, { title: params.title });
369
+
370
+ const { data } = await this.octokit.issues.create({
371
+ owner,
372
+ repo,
373
+ title: params.title,
374
+ body: params.body,
375
+ labels: params.labels,
376
+ assignees: params.assignees,
377
+ });
378
+
379
+ return data as unknown as Issue;
380
+ }
381
+
382
+ /**
383
+ * Update an issue
384
+ */
385
+ async updateIssue(
386
+ owner: string,
387
+ repo: string,
388
+ issueNumber: number,
389
+ params: Partial<CreateIssueParams> & { state?: 'open' | 'closed' }
390
+ ): Promise<Issue> {
391
+ logger.info(`Updating issue #${issueNumber} in ${owner}/${repo}`);
392
+
393
+ const { data } = await this.octokit.issues.update({
394
+ owner,
395
+ repo,
396
+ issue_number: issueNumber,
397
+ ...params,
398
+ });
399
+
400
+ return data as unknown as Issue;
401
+ }
402
+
403
+ /**
404
+ * Close an issue
405
+ */
406
+ async closeIssue(owner: string, repo: string, issueNumber: number): Promise<Issue> {
407
+ return this.updateIssue(owner, repo, issueNumber, { state: 'closed' });
408
+ }
409
+
410
+ /**
411
+ * Add a comment to an issue or PR
412
+ */
413
+ async addComment(
414
+ owner: string,
415
+ repo: string,
416
+ issueNumber: number,
417
+ body: string
418
+ ): Promise<IssueComment> {
419
+ logger.info(`Adding comment to #${issueNumber} in ${owner}/${repo}`);
420
+
421
+ const { data } = await this.octokit.issues.createComment({
422
+ owner,
423
+ repo,
424
+ issue_number: issueNumber,
425
+ body,
426
+ });
427
+
428
+ return data as unknown as IssueComment;
429
+ }
430
+
431
+ /**
432
+ * List comments on an issue or PR
433
+ */
434
+ async listComments(
435
+ owner: string,
436
+ repo: string,
437
+ issueNumber: number,
438
+ perPage = 30
439
+ ): Promise<IssueComment[]> {
440
+ logger.info(`Listing comments for #${issueNumber} in ${owner}/${repo}`);
441
+
442
+ const { data } = await this.octokit.issues.listComments({
443
+ owner,
444
+ repo,
445
+ issue_number: issueNumber,
446
+ per_page: perPage,
447
+ });
448
+
449
+ return data as unknown as IssueComment[];
450
+ }
451
+
452
+ // ==========================================
453
+ // Repository Operations
454
+ // ==========================================
455
+
456
+ /**
457
+ * Get repository information
458
+ */
459
+ async getRepo(owner: string, repo: string): Promise<Repository> {
460
+ logger.info(`Getting repository ${owner}/${repo}`);
461
+
462
+ const { data } = await this.octokit.repos.get({ owner, repo });
463
+
464
+ return data as unknown as Repository;
465
+ }
466
+
467
+ /**
468
+ * List branches for a repository
469
+ */
470
+ async listBranches(owner: string, repo: string, perPage = 30): Promise<Branch[]> {
471
+ logger.info(`Listing branches for ${owner}/${repo}`);
472
+
473
+ const { data } = await this.octokit.repos.listBranches({
474
+ owner,
475
+ repo,
476
+ per_page: perPage,
477
+ });
478
+
479
+ return data as unknown as Branch[];
480
+ }
481
+
482
+ /**
483
+ * Get a specific branch
484
+ */
485
+ async getBranch(
486
+ owner: string,
487
+ repo: string,
488
+ branch: string
489
+ ): Promise<Branch & { commit: { sha: string } }> {
490
+ logger.info(`Getting branch ${branch} for ${owner}/${repo}`);
491
+
492
+ const { data } = await this.octokit.repos.getBranch({ owner, repo, branch });
493
+
494
+ return data as unknown as Branch & { commit: { sha: string } };
495
+ }
496
+
497
+ /**
498
+ * Create a new branch
499
+ */
500
+ async createBranch(
501
+ owner: string,
502
+ repo: string,
503
+ branchName: string,
504
+ sha: string
505
+ ): Promise<{ ref: string; object: { sha: string } }> {
506
+ logger.info(`Creating branch ${branchName} in ${owner}/${repo}`);
507
+
508
+ const { data } = await this.octokit.git.createRef({
509
+ owner,
510
+ repo,
511
+ ref: `refs/heads/${branchName}`,
512
+ sha,
513
+ });
514
+
515
+ return data;
516
+ }
517
+
518
+ /**
519
+ * Delete a branch
520
+ */
521
+ async deleteBranch(owner: string, repo: string, branchName: string): Promise<void> {
522
+ logger.info(`Deleting branch ${branchName} in ${owner}/${repo}`);
523
+
524
+ await this.octokit.git.deleteRef({
525
+ owner,
526
+ repo,
527
+ ref: `heads/${branchName}`,
528
+ });
529
+ }
530
+
531
+ // ==========================================
532
+ // Authentication
533
+ // ==========================================
534
+
535
+ /**
536
+ * Validate the token and get authenticated user
537
+ */
538
+ async validateToken(): Promise<{ login: string; name: string | null; email: string | null }> {
539
+ const { data } = await this.octokit.users.getAuthenticated();
540
+ return {
541
+ login: data.login,
542
+ name: data.name,
543
+ email: data.email,
544
+ };
545
+ }
546
+
547
+ // ==========================================
548
+ // GitHub Actions Operations
549
+ // ==========================================
550
+
551
+ /**
552
+ * List workflow runs for a repository
553
+ */
554
+ async listWorkflowRuns(
555
+ owner: string,
556
+ repo: string,
557
+ options?: WorkflowRunOptions
558
+ ): Promise<WorkflowRun[]> {
559
+ logger.info(`Listing workflow runs for ${owner}/${repo}`);
560
+
561
+ const params: any = {
562
+ owner,
563
+ repo,
564
+ per_page: options?.perPage || 30,
565
+ };
566
+
567
+ if (options?.workflowId) {
568
+ params.workflow_id = options.workflowId;
569
+ }
570
+ if (options?.branch) {
571
+ params.branch = options.branch;
572
+ }
573
+ if (options?.event) {
574
+ params.event = options.event;
575
+ }
576
+ if (options?.status) {
577
+ params.status = options.status;
578
+ }
579
+
580
+ const { data } = await this.octokit.actions.listWorkflowRunsForRepo(params);
581
+
582
+ return data.workflow_runs as unknown as WorkflowRun[];
583
+ }
584
+
585
+ /**
586
+ * Get a specific workflow run
587
+ */
588
+ async getWorkflowRun(owner: string, repo: string, runId: number): Promise<WorkflowRun> {
589
+ logger.info(`Getting workflow run ${runId} for ${owner}/${repo}`);
590
+
591
+ const { data } = await this.octokit.actions.getWorkflowRun({
592
+ owner,
593
+ repo,
594
+ run_id: runId,
595
+ });
596
+
597
+ return data as unknown as WorkflowRun;
598
+ }
599
+
600
+ /**
601
+ * Trigger a workflow dispatch event
602
+ */
603
+ async triggerWorkflow(
604
+ owner: string,
605
+ repo: string,
606
+ workflowId: string | number,
607
+ ref: string,
608
+ inputs?: Record<string, string>
609
+ ): Promise<void> {
610
+ logger.info(`Triggering workflow ${workflowId} for ${owner}/${repo}`);
611
+
612
+ await this.octokit.actions.createWorkflowDispatch({
613
+ owner,
614
+ repo,
615
+ workflow_id: workflowId,
616
+ ref,
617
+ inputs,
618
+ });
619
+ }
620
+
621
+ /**
622
+ * List workflows for a repository
623
+ */
624
+ async listWorkflows(owner: string, repo: string, perPage = 30): Promise<Workflow[]> {
625
+ logger.info(`Listing workflows for ${owner}/${repo}`);
626
+
627
+ const { data } = await this.octokit.actions.listRepoWorkflows({
628
+ owner,
629
+ repo,
630
+ per_page: perPage,
631
+ });
632
+
633
+ return data.workflows as unknown as Workflow[];
634
+ }
635
+
636
+ /**
637
+ * Cancel a workflow run
638
+ */
639
+ async cancelWorkflowRun(owner: string, repo: string, runId: number): Promise<void> {
640
+ logger.info(`Cancelling workflow run ${runId} for ${owner}/${repo}`);
641
+
642
+ await this.octokit.actions.cancelWorkflowRun({
643
+ owner,
644
+ repo,
645
+ run_id: runId,
646
+ });
647
+ }
648
+
649
+ /**
650
+ * Re-run a workflow
651
+ */
652
+ async rerunWorkflow(owner: string, repo: string, runId: number): Promise<void> {
653
+ logger.info(`Re-running workflow ${runId} for ${owner}/${repo}`);
654
+
655
+ await this.octokit.actions.reRunWorkflow({
656
+ owner,
657
+ repo,
658
+ run_id: runId,
659
+ });
660
+ }
661
+
662
+ /**
663
+ * Get workflow run logs
664
+ */
665
+ async getWorkflowRunLogs(owner: string, repo: string, runId: number): Promise<string> {
666
+ logger.info(`Getting logs for workflow run ${runId}`);
667
+
668
+ const { url } = await this.octokit.actions.downloadWorkflowRunLogs({
669
+ owner,
670
+ repo,
671
+ run_id: runId,
672
+ });
673
+
674
+ return url;
675
+ }
676
+
677
+ // ==========================================
678
+ // Release Operations
679
+ // ==========================================
680
+
681
+ /**
682
+ * Create a release
683
+ */
684
+ async createRelease(owner: string, repo: string, options: ReleaseOptions): Promise<Release> {
685
+ logger.info(`Creating release ${options.tagName} for ${owner}/${repo}`);
686
+
687
+ const { data } = await this.octokit.repos.createRelease({
688
+ owner,
689
+ repo,
690
+ tag_name: options.tagName,
691
+ target_commitish: options.targetCommitish,
692
+ name: options.name,
693
+ body: options.body,
694
+ draft: options.draft,
695
+ prerelease: options.prerelease,
696
+ generate_release_notes: options.generateReleaseNotes,
697
+ });
698
+
699
+ return data as unknown as Release;
700
+ }
701
+
702
+ /**
703
+ * List releases
704
+ */
705
+ async listReleases(owner: string, repo: string, perPage = 30): Promise<Release[]> {
706
+ logger.info(`Listing releases for ${owner}/${repo}`);
707
+
708
+ const { data } = await this.octokit.repos.listReleases({
709
+ owner,
710
+ repo,
711
+ per_page: perPage,
712
+ });
713
+
714
+ return data as unknown as Release[];
715
+ }
716
+
717
+ /**
718
+ * Get a release by tag
719
+ */
720
+ async getReleaseByTag(owner: string, repo: string, tag: string): Promise<Release> {
721
+ logger.info(`Getting release by tag ${tag} for ${owner}/${repo}`);
722
+
723
+ const { data } = await this.octokit.repos.getReleaseByTag({ owner, repo, tag });
724
+
725
+ return data as unknown as Release;
726
+ }
727
+
728
+ /**
729
+ * Get the latest release
730
+ */
731
+ async getLatestRelease(owner: string, repo: string): Promise<Release> {
732
+ logger.info(`Getting latest release for ${owner}/${repo}`);
733
+
734
+ const { data } = await this.octokit.repos.getLatestRelease({ owner, repo });
735
+
736
+ return data as unknown as Release;
737
+ }
738
+
739
+ /**
740
+ * Update a release
741
+ */
742
+ async updateRelease(
743
+ owner: string,
744
+ repo: string,
745
+ releaseId: number,
746
+ options: Partial<ReleaseOptions>
747
+ ): Promise<Release> {
748
+ logger.info(`Updating release ${releaseId} for ${owner}/${repo}`);
749
+
750
+ const { data } = await this.octokit.repos.updateRelease({
751
+ owner,
752
+ repo,
753
+ release_id: releaseId,
754
+ tag_name: options.tagName,
755
+ target_commitish: options.targetCommitish,
756
+ name: options.name,
757
+ body: options.body,
758
+ draft: options.draft,
759
+ prerelease: options.prerelease,
760
+ });
761
+
762
+ return data as unknown as Release;
763
+ }
764
+
765
+ /**
766
+ * Delete a release
767
+ */
768
+ async deleteRelease(owner: string, repo: string, releaseId: number): Promise<void> {
769
+ logger.info(`Deleting release ${releaseId} for ${owner}/${repo}`);
770
+
771
+ await this.octokit.repos.deleteRelease({
772
+ owner,
773
+ repo,
774
+ release_id: releaseId,
775
+ });
776
+ }
777
+
778
+ /**
779
+ * Generate release notes
780
+ */
781
+ async generateReleaseNotes(
782
+ owner: string,
783
+ repo: string,
784
+ tagName: string,
785
+ options?: { previousTagName?: string; targetCommitish?: string }
786
+ ): Promise<{ name: string; body: string }> {
787
+ logger.info(`Generating release notes for ${tagName}`);
788
+
789
+ const { data } = await this.octokit.repos.generateReleaseNotes({
790
+ owner,
791
+ repo,
792
+ tag_name: tagName,
793
+ previous_tag_name: options?.previousTagName,
794
+ target_commitish: options?.targetCommitish,
795
+ });
796
+
797
+ return { name: data.name, body: data.body };
798
+ }
799
+ }