| |
| |
|
|
|
|
| const GITLAB_URL = process.env.GITLAB_URL || 'https://gitlab.com'
|
| const GITLAB_TOKEN = process.env.GITLAB_TOKEN || ''
|
|
|
| async function glFetch(path, opts = {}) {
|
| const res = await fetch(`${GITLAB_URL}/api/v4${path}`, {
|
| ...opts,
|
| headers: {
|
| 'Content-Type': 'application/json',
|
| 'PRIVATE-TOKEN': GITLAB_TOKEN,
|
| ...(opts.headers || {}),
|
| },
|
| })
|
| return res
|
| }
|
|
|
|
|
| async function postMRComment(projectId, mrIid, body) {
|
| if (!GITLAB_TOKEN || !projectId) return
|
| await glFetch(`/projects/${encodeURIComponent(projectId)}/merge_requests/${mrIid}/notes`, {
|
| method: 'POST',
|
| body: JSON.stringify({ body }),
|
| })
|
| }
|
|
|
|
|
| async function postCommitComment(projectId, sha, note) {
|
| if (!GITLAB_TOKEN || !projectId || !sha) return
|
| await glFetch(`/projects/${encodeURIComponent(projectId)}/repository/commits/${sha}/comments`, {
|
| method: 'POST',
|
| body: JSON.stringify({ note }),
|
| })
|
| }
|
|
|
|
|
| function formatGitLabComment(pipeline, result) {
|
| const steps = result.steps || []
|
| const review = result.final_out || ''
|
| const worm = result.worm?.hash || ''
|
|
|
| const brain = steps.find(s => s.step === 'BRAIN')
|
| const legs = steps.find(s => s.step === 'LEGS')
|
|
|
| const verdict = review.match(/PASS|APPROVE/i) ? 'β
'
|
| : review.match(/WARN|REQUEST_CHANGES/i) ? 'β οΈ'
|
| : review.match(/BLOCK|REJECT/i) ? 'π«'
|
| : 'π'
|
|
|
| return `## ${verdict} SnapKitty Sovereign Review
|
|
|
| > Pipeline: \`${pipeline}\` · WORM: \`${worm}\` · ⬑ Ω ⺠Ψ ΠΠΣ Φ α
|
|
|
| ### π§ Brain Analysis
|
| ${brain?.output?.slice(0, 800) || '_Brain offline_'}
|
|
|
| ### 𦡠Legs Implementation
|
| \`\`\`
|
| ${legs?.output?.slice(0, 600) || '_Legs offline_'}
|
| \`\`\`
|
|
|
| ### π Sovereign Review
|
| ${review?.slice(0, 1000) || '_No review_'}
|
|
|
| ---
|
| *Powered by [SnapKitty](https://snapkitty.dev) Β· Frankenstein workflow Β· Granite Code 3B local GPU*
|
| `
|
| }
|
|
|
|
|
| export async function postToGitLab(pipeline, context, result) {
|
| if (!GITLAB_TOKEN) {
|
| console.log('[GITLAB API] No token β skipping post-back')
|
| return
|
| }
|
|
|
| const comment = formatGitLabComment(pipeline, result)
|
|
|
| switch (pipeline) {
|
| case 'mr-review':
|
| case 'direct-command':
|
| if (context.mr_id) {
|
| const projectId = process.env.GITLAB_PROJECT_ID || context.project_id
|
| await postMRComment(projectId, context.mr_id, comment)
|
| console.log(`[GITLAB API] Comment posted to MR #${context.mr_id}`)
|
| }
|
| break
|
|
|
| case 'code-review':
|
|
|
| console.log(`[GITLAB API] Code review complete for ${context.repo}@${context.branch}`)
|
|
|
| break
|
|
|
| case 'pipeline-diagnose':
|
| case 'job-fix':
|
|
|
| console.log(`[GITLAB API] Pipeline diagnosis ready for #${context.pipeline_id}`)
|
| break
|
| }
|
| }
|
|
|