stella-coder 5.3.1 → 5.3.2
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/COMMANDS.md +47 -0
- package/install-av.bat +17 -0
- package/install-stella-pkg.bat +21 -0
- package/oneline-av.ps1 +7 -0
- package/oneline-stella.ps1 +2 -0
- package/package.json +1 -1
- package/releases/stella-antivirus/database.mjs +871 -0
- package/releases/stella-antivirus/index.mjs +8 -0
- package/releases/stella-antivirus/install-av.bat +12 -0
- package/releases/stella-antivirus/scanner.mjs +591 -0
- package/releases/stella-antivirus/ui.mjs +570 -0
- package/releases/stella-antivirus.zip +0 -0
- package/releases/stella-coder/README.md +67 -0
- package/releases/stella-coder/adb.mjs +200 -0
- package/releases/stella-coder/autonomous-agent.mjs +550 -0
- package/releases/stella-coder/banner.mjs +46 -0
- package/releases/stella-coder/browser-control.mjs +274 -0
- package/releases/stella-coder/build.mjs +151 -0
- package/releases/stella-coder/charts.mjs +411 -0
- package/releases/stella-coder/coding-brain.mjs +753 -0
- package/releases/stella-coder/game-engine.mjs +708 -0
- package/releases/stella-coder/gdrive-backup.mjs +338 -0
- package/releases/stella-coder/git-api.mjs +407 -0
- package/releases/stella-coder/gmail.mjs +415 -0
- package/releases/stella-coder/home-assistant.mjs +168 -0
- package/releases/stella-coder/index.mjs +5810 -0
- package/releases/stella-coder/install-stella.bat +12 -0
- package/releases/stella-coder/markdown.mjs +100 -0
- package/releases/stella-coder/mcp.mjs +296 -0
- package/releases/stella-coder/package.json +67 -0
- package/releases/stella-coder/presentations.mjs +1106 -0
- package/releases/stella-coder/protect.mjs +182 -0
- package/releases/stella-coder/screen-monitor.mjs +334 -0
- package/releases/stella-coder/sea-config.json +5 -0
- package/releases/stella-coder/security.mjs +237 -0
- package/releases/stella-coder/subagents.mjs +142 -0
- package/releases/stella-coder/telegram-bot.mjs +824 -0
- package/releases/stella-coder/tg-server.mjs +116 -0
- package/releases/stella-coder/theme.mjs +91 -0
- package/releases/stella-coder/tools.mjs +3143 -0
- package/releases/stella-coder/web-parser.mjs +229 -0
- package/releases/stella-coder/yandex-maps.mjs +426 -0
- package/releases/stella-coder.zip +0 -0
- package/run-antivirus.bat +4 -0
- package/setup-antivirus.bat +64 -0
- package/setup-full.bat +65 -0
- package/setup-stella.bat +46 -0
- package/stella-cli/index.mjs +11 -1
- package/stella-cli/protect.mjs +182 -0
- package/stella.bat +3 -0
- package/tests/test-modules.mjs +101 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
import { execSync } from "child_process"
|
|
2
|
+
import { readFileSync, existsSync } from "fs"
|
|
3
|
+
import { join } from "path"
|
|
4
|
+
import http from "http"
|
|
5
|
+
import https from "https"
|
|
6
|
+
|
|
7
|
+
function apiRequest(url, options = {}) {
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
const mod = url.startsWith("https") ? https : http
|
|
10
|
+
const urlObj = new URL(url)
|
|
11
|
+
const headers = {
|
|
12
|
+
"Accept": "application/vnd.github+json",
|
|
13
|
+
...options.headers,
|
|
14
|
+
}
|
|
15
|
+
if (options.token) headers["Authorization"] = `Bearer ${options.token}`
|
|
16
|
+
|
|
17
|
+
const reqOptions = {
|
|
18
|
+
hostname: urlObj.hostname,
|
|
19
|
+
port: urlObj.port,
|
|
20
|
+
path: urlObj.pathname + urlObj.search,
|
|
21
|
+
method: options.method || "GET",
|
|
22
|
+
headers,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const req = mod.request(reqOptions, (res) => {
|
|
26
|
+
let data = ""
|
|
27
|
+
res.on("data", (chunk) => data += chunk)
|
|
28
|
+
res.on("end", () => {
|
|
29
|
+
try { resolve({ status: res.statusCode, data: JSON.parse(data) }) }
|
|
30
|
+
catch { resolve({ status: res.statusCode, data }) }
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
req.on("error", reject)
|
|
34
|
+
if (options.body) req.write(JSON.stringify(options.body))
|
|
35
|
+
req.end()
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getGitRemote() {
|
|
40
|
+
try {
|
|
41
|
+
const remote = execSync("git remote get-url origin", { encoding: "utf-8" }).trim()
|
|
42
|
+
// Parse owner/repo from URL
|
|
43
|
+
const match = remote.match(/github\.com[/:]([^/]+)\/([^/.]+)/)
|
|
44
|
+
if (match) return { provider: "github", owner: match[1], repo: match[2] }
|
|
45
|
+
const glMatch = remote.match(/gitlab\.com[/:]([^/]+)\/([^/.]+)/)
|
|
46
|
+
if (glMatch) return { provider: "gitlab", owner: glMatch[1], repo: glMatch[2] }
|
|
47
|
+
return { provider: "unknown", remote }
|
|
48
|
+
} catch {
|
|
49
|
+
return null
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function getToken(provider) {
|
|
54
|
+
// Try environment variables
|
|
55
|
+
if (provider === "github") return process.env.GITHUB_TOKEN || process.env.GH_TOKEN
|
|
56
|
+
if (provider === "gitlab") return process.env.GITLAB_TOKEN || process.env.GL_TOKEN
|
|
57
|
+
|
|
58
|
+
// Try git credential
|
|
59
|
+
try {
|
|
60
|
+
const config = execSync("git config --get credential.helper", { encoding: "utf-8" }).trim()
|
|
61
|
+
if (config.includes("store")) {
|
|
62
|
+
const credPath = join(process.env.USERPROFILE || process.env.HOME || "", ".git-credentials")
|
|
63
|
+
if (existsSync(credPath)) {
|
|
64
|
+
const creds = readFileSync(credPath, "utf-8")
|
|
65
|
+
const match = creds.match(/https:\/\/[^:]+:([^@]+)@github\.com/)
|
|
66
|
+
if (match) return match[1]
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
} catch {}
|
|
70
|
+
|
|
71
|
+
return null
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export class GitAPI {
|
|
75
|
+
constructor() {
|
|
76
|
+
this.info = getGitRemote()
|
|
77
|
+
this.token = this.info ? getToken(this.info.provider) : null
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
isConfigured() {
|
|
81
|
+
return this.info && this.info.provider !== "unknown"
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
hasToken() {
|
|
85
|
+
return !!this.token
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ===== ISSUES =====
|
|
89
|
+
async listIssues(state = "open", perPage = 20) {
|
|
90
|
+
if (!this.isConfigured()) return { success: false, error: "No GitHub/GitLab remote configured" }
|
|
91
|
+
const { provider, owner, repo } = this.info
|
|
92
|
+
const token = this.token
|
|
93
|
+
|
|
94
|
+
if (provider === "github") {
|
|
95
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/issues?state=${state}&per_page=${perPage}`
|
|
96
|
+
const res = await apiRequest(url, { token: this.token })
|
|
97
|
+
return { success: true, issues: Array.isArray(res.data) ? res.data : [] }
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (provider === "gitlab") {
|
|
101
|
+
const encoded = encodeURIComponent(`${owner}/${repo}`)
|
|
102
|
+
const url = `https://gitlab.com/api/v4/projects/${encoded}/issues?state=${state}`
|
|
103
|
+
const res = await apiRequest(url, { token: this.token })
|
|
104
|
+
return { success: true, issues: Array.isArray(res.data) ? res.data : [] }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return { success: false, error: "Unknown provider" }
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async createIssue(title, body, labels = []) {
|
|
111
|
+
if (!this.isConfigured()) return { success: false, error: "No git remote configured" }
|
|
112
|
+
|
|
113
|
+
const { provider, owner, repo } = this.info
|
|
114
|
+
|
|
115
|
+
if (provider === "github") {
|
|
116
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/issues`
|
|
117
|
+
const res = await apiRequest(url, {
|
|
118
|
+
method: "POST",
|
|
119
|
+
token: this.token,
|
|
120
|
+
body: { title, body, labels },
|
|
121
|
+
})
|
|
122
|
+
return { success: res.status === 201, data: res.data, url: res.data?.html_url }
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (provider === "gitlab") {
|
|
126
|
+
const encoded = encodeURIComponent(`${owner}/${repo}`)
|
|
127
|
+
const url = `https://gitlab.com/api/v4/projects/${encoded}/issues`
|
|
128
|
+
const res = await apiRequest(url, {
|
|
129
|
+
method: "POST",
|
|
130
|
+
token: this.token,
|
|
131
|
+
body: { title, description: body, labels: labels.join(",") },
|
|
132
|
+
})
|
|
133
|
+
return { success: res.status === 201, data: res.data, url: res.data?.web_url }
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return { success: false, error: "Unknown provider" }
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async closeIssue(issueNumber) {
|
|
140
|
+
if (!this.isConfigured()) return { success: false, error: "No git remote configured" }
|
|
141
|
+
|
|
142
|
+
const { provider, owner, repo } = this.info
|
|
143
|
+
|
|
144
|
+
if (provider === "github") {
|
|
145
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/issues/${issueNumber}`
|
|
146
|
+
const res = await apiRequest(url, {
|
|
147
|
+
method: "PATCH",
|
|
148
|
+
token: this.token,
|
|
149
|
+
body: { state: "closed" },
|
|
150
|
+
})
|
|
151
|
+
return { success: res.status === 200, data: res.data }
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (provider === "gitlab") {
|
|
155
|
+
const encoded = encodeURIComponent(`${owner}/${repo}`)
|
|
156
|
+
const url = `https://gitlab.com/api/v4/projects/${encoded}/issues/${issueNumber}`
|
|
157
|
+
const res = await apiRequest(url, {
|
|
158
|
+
method: "PUT",
|
|
159
|
+
token: this.token,
|
|
160
|
+
body: { state_event: "close" },
|
|
161
|
+
})
|
|
162
|
+
return { success: res.status === 200, data: res.data }
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return { success: false, error: "Unknown provider" }
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ===== PULL REQUESTS / MERGE REQUESTS =====
|
|
169
|
+
async listPRs(state = "open") {
|
|
170
|
+
if (!this.isConfigured()) return { success: false, error: "No git remote configured" }
|
|
171
|
+
|
|
172
|
+
const { provider, owner, repo } = this.info
|
|
173
|
+
|
|
174
|
+
if (provider === "github") {
|
|
175
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/pulls?state=${state}`
|
|
176
|
+
const res = await apiRequest(url, { token: this.token })
|
|
177
|
+
return { success: true, prs: Array.isArray(res.data) ? res.data : [] }
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (provider === "gitlab") {
|
|
181
|
+
const encoded = encodeURIComponent(`${owner}/${repo}`)
|
|
182
|
+
const stateMap = { open: "opened", closed: "closed", merged: "merged" }
|
|
183
|
+
const url = `https://gitlab.com/api/v4/projects/${encoded}/merge_requests?state=${stateMap[state] || state}`
|
|
184
|
+
const res = await apiRequest(url, { token: this.token })
|
|
185
|
+
return { success: true, prs: Array.isArray(res.data) ? res.data : [] }
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return { success: false, error: "Unknown provider" }
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async createPR(title, body, head = "main", base = "main") {
|
|
192
|
+
if (!this.isConfigured()) return { success: false, error: "No git remote configured" }
|
|
193
|
+
|
|
194
|
+
const { provider, owner, repo } = this.info
|
|
195
|
+
|
|
196
|
+
if (provider === "github") {
|
|
197
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/pulls`
|
|
198
|
+
const res = await apiRequest(url, {
|
|
199
|
+
method: "POST",
|
|
200
|
+
token: this.token,
|
|
201
|
+
body: { title, body, head, base },
|
|
202
|
+
})
|
|
203
|
+
return { success: res.status === 201, data: res.data, url: res.data?.html_url }
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (provider === "gitlab") {
|
|
207
|
+
const encoded = encodeURIComponent(`${owner}/${repo}`)
|
|
208
|
+
const url = `https://gitlab.com/api/v4/projects/${encoded}/merge_requests`
|
|
209
|
+
const res = await apiRequest(url, {
|
|
210
|
+
method: "POST",
|
|
211
|
+
token: this.token,
|
|
212
|
+
body: { title, description: body, source_branch: head, target_branch: base },
|
|
213
|
+
})
|
|
214
|
+
return { success: res.status === 201, data: res.data, url: res.data?.web_url }
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return { success: false, error: "Unknown provider" }
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
async reviewPR(prNumber, event, body) {
|
|
221
|
+
if (!this.isConfigured()) return { success: false, error: "No git remote configured" }
|
|
222
|
+
|
|
223
|
+
const { provider, owner, repo } = this.info
|
|
224
|
+
|
|
225
|
+
if (provider === "github") {
|
|
226
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/reviews`
|
|
227
|
+
const res = await apiRequest(url, {
|
|
228
|
+
method: "POST",
|
|
229
|
+
token: this.token,
|
|
230
|
+
body: { event, body },
|
|
231
|
+
})
|
|
232
|
+
return { success: res.status === 200 || res.status === 201, data: res.data }
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (provider === "gitlab") {
|
|
236
|
+
const encoded = encodeURIComponent(`${owner}/${repo}`)
|
|
237
|
+
const url = `https://gitlab.com/api/v4/projects/${encoded}/merge_requests/${prNumber}/approvals`
|
|
238
|
+
const res = await apiRequest(url, {
|
|
239
|
+
method: "POST",
|
|
240
|
+
token: this.token,
|
|
241
|
+
})
|
|
242
|
+
return { success: res.status === 201, data: res.data }
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return { success: false, error: "Unknown provider" }
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
async mergePR(prNumber) {
|
|
249
|
+
if (!this.isConfigured()) return { success: false, error: "No git remote configured" }
|
|
250
|
+
|
|
251
|
+
const { provider, owner, repo } = this.info
|
|
252
|
+
|
|
253
|
+
if (provider === "github") {
|
|
254
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/merge`
|
|
255
|
+
const res = await apiRequest(url, {
|
|
256
|
+
method: "PUT",
|
|
257
|
+
token: this.token,
|
|
258
|
+
body: { merge_method: "squash" },
|
|
259
|
+
})
|
|
260
|
+
return { success: res.status === 200, data: res.data }
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (provider === "gitlab") {
|
|
264
|
+
const encoded = encodeURIComponent(`${owner}/${repo}`)
|
|
265
|
+
const url = `https://gitlab.com/api/v4/projects/${encoded}/merge_requests/${prNumber}/merge`
|
|
266
|
+
const res = await apiRequest(url, {
|
|
267
|
+
method: "PUT",
|
|
268
|
+
token: this.token,
|
|
269
|
+
})
|
|
270
|
+
return { success: res.status === 200, data: res.data }
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return { success: false, error: "Unknown provider" }
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// ===== CODE REVIEW =====
|
|
277
|
+
async getPRFiles(prNumber) {
|
|
278
|
+
if (!this.isConfigured()) return { success: false, error: "No git remote configured" }
|
|
279
|
+
|
|
280
|
+
const { provider, owner, repo } = this.info
|
|
281
|
+
|
|
282
|
+
if (provider === "github") {
|
|
283
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/files`
|
|
284
|
+
const res = await apiRequest(url, { token: this.token })
|
|
285
|
+
return { success: true, files: Array.isArray(res.data) ? res.data : [] }
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (provider === "gitlab") {
|
|
289
|
+
const encoded = encodeURIComponent(`${owner}/${repo}`)
|
|
290
|
+
const url = `https://gitlab.com/api/v4/projects/${encoded}/merge_requests/${prNumber}/changes`
|
|
291
|
+
const res = await apiRequest(url, { token: this.token })
|
|
292
|
+
return { success: true, files: res.data?.changes || [] }
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return { success: false, error: "Unknown provider" }
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
async addComment(prNumber, body, filePath, position) {
|
|
299
|
+
if (!this.isConfigured()) return { success: false, error: "No git remote configured" }
|
|
300
|
+
|
|
301
|
+
const { provider, owner, repo } = this.info
|
|
302
|
+
|
|
303
|
+
if (provider === "github" && filePath && position) {
|
|
304
|
+
// Get latest commit SHA
|
|
305
|
+
const prUrl = `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}`
|
|
306
|
+
const prRes = await apiRequest(prUrl, { token: this.token })
|
|
307
|
+
const commitId = prRes.data?.head?.sha
|
|
308
|
+
|
|
309
|
+
if (commitId) {
|
|
310
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/comments`
|
|
311
|
+
const res = await apiRequest(url, {
|
|
312
|
+
method: "POST",
|
|
313
|
+
token: this.token,
|
|
314
|
+
body: { body, path: filePath, position, commit_id: commitId },
|
|
315
|
+
})
|
|
316
|
+
return { success: res.status === 201, data: res.data }
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Fallback: general comment
|
|
321
|
+
return await this.reviewPR(prNumber, "COMMENT", body)
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// ===== REPOS =====
|
|
325
|
+
async getRepoInfo() {
|
|
326
|
+
if (!this.isConfigured()) return { success: false, error: "No git remote configured" }
|
|
327
|
+
|
|
328
|
+
const { provider, owner, repo } = this.info
|
|
329
|
+
|
|
330
|
+
if (provider === "github") {
|
|
331
|
+
const url = `https://api.github.com/repos/${owner}/${repo}`
|
|
332
|
+
const res = await apiRequest(url, { token: this.token })
|
|
333
|
+
return { success: true, repo: res.data }
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (provider === "gitlab") {
|
|
337
|
+
const encoded = encodeURIComponent(`${owner}/${repo}`)
|
|
338
|
+
const url = `https://gitlab.com/api/v4/projects/${encoded}`
|
|
339
|
+
const res = await apiRequest(url, { token: this.token })
|
|
340
|
+
return { success: true, repo: res.data }
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return { success: false, error: "Unknown provider" }
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
async listBranches() {
|
|
347
|
+
if (!this.isConfigured()) return { success: false, error: "No git remote configured" }
|
|
348
|
+
|
|
349
|
+
const { provider, owner, repo } = this.info
|
|
350
|
+
|
|
351
|
+
if (provider === "github") {
|
|
352
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/branches`
|
|
353
|
+
const res = await apiRequest(url, { token: this.token })
|
|
354
|
+
return { success: true, branches: Array.isArray(res.data) ? res.data.map(b => b.name) : [] }
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (provider === "gitlab") {
|
|
358
|
+
const encoded = encodeURIComponent(`${owner}/${repo}`)
|
|
359
|
+
const url = `https://gitlab.com/api/v4/projects/${encoded}/repository/branches`
|
|
360
|
+
const res = await apiRequest(url, { token: this.token })
|
|
361
|
+
return { success: true, branches: Array.isArray(res.data) ? res.data.map(b => b.name) : [] }
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return { success: false, error: "Unknown provider" }
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
async listReleases() {
|
|
368
|
+
if (!this.isConfigured()) return { success: false, error: "No git remote configured" }
|
|
369
|
+
|
|
370
|
+
const { provider, owner, repo } = this.info
|
|
371
|
+
|
|
372
|
+
if (provider === "github") {
|
|
373
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/releases`
|
|
374
|
+
const res = await apiRequest(url, { token: this.token })
|
|
375
|
+
return { success: true, releases: Array.isArray(res.data) ? res.data : [] }
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (provider === "gitlab") {
|
|
379
|
+
const encoded = encodeURIComponent(`${owner}/${repo}`)
|
|
380
|
+
const url = `https://gitlab.com/api/v4/projects/${encoded}/releases`
|
|
381
|
+
const res = await apiRequest(url, { token: this.token })
|
|
382
|
+
return { success: true, releases: Array.isArray(res.data) ? res.data : [] }
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return { success: false, error: "Unknown provider" }
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
async createRelease(tag, name, body) {
|
|
389
|
+
if (!this.isConfigured()) return { success: false, error: "No git remote configured" }
|
|
390
|
+
|
|
391
|
+
const { provider, owner, repo } = this.info
|
|
392
|
+
|
|
393
|
+
if (provider === "github") {
|
|
394
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/releases`
|
|
395
|
+
const res = await apiRequest(url, {
|
|
396
|
+
method: "POST",
|
|
397
|
+
token: this.token,
|
|
398
|
+
body: { tag_name: tag, name, body },
|
|
399
|
+
})
|
|
400
|
+
return { success: res.status === 201, data: res.data, url: res.data?.html_url }
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
return { success: false, error: "Release creation only supported on GitHub" }
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
export default GitAPI
|