CoolFace
Apppublic

delqhi/sin-github-issues

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
profile.ts116 linesDownload Raw Back to src
1import { runCommand, runJsonCommand } from './command.js';2import { recordAuditEvent } from './audit.js';3 4export async function getProfile() {5  const profile = await runJsonCommand<{6    login: string;7    id: number;8    name: string | null;9    company: string | null;10    blog: string | null;11    location: string | null;12    bio: string | null;13    twitter_username: string | null;14    hireable: boolean | null;15    public_repos: number;16    followers: number;17    following: number;18    html_url: string;19  }>('gh', ['api', 'user']);20  return { ok: true, profile };21}22 23export async function updateProfile(input: {24  name?: string;25  company?: string;26  blog?: string;27  location?: string;28  bio?: string;29  twitter_username?: string;30  hireable?: boolean;31}) {32  const args = ['api', 'user', '--method', 'PATCH'];33  if (input.name !== undefined) args.push('-f', `name=${input.name}`);34  if (input.company !== undefined) args.push('-f', `company=${input.company}`);35  if (input.blog !== undefined) args.push('-f', `blog=${input.blog}`);36  if (input.location !== undefined) args.push('-f', `location=${input.location}`);37  if (input.bio !== undefined) args.push('-f', `bio=${input.bio}`);38  if (input.twitter_username !== undefined) args.push('-f', `twitter_username=${input.twitter_username}`);39  if (input.hireable !== undefined) args.push('-F', `hireable=${input.hireable}`);40  const result = await runJsonCommand<object>('gh', args);41  await recordAuditEvent({ kind: 'profile.update', result });42  return { ok: true, profile: result };43}44 45export async function listPinnedRepos() {46  const query = `47    query {48      user(login: "Delqhi") {49        pinnedItems(first: 6, types: REPOSITORY) {50          nodes {51            ... on Repository {52              id53              name54              description55              url56              isFork57              stargazerCount58              primaryLanguage { name }59            }60          }61        }62      }63    }64  `.replace(/\s+/g, ' ');65  const response = await runJsonCommand<{ data: { user: { pinnedItems: { nodes: Array<{ id: string; name: string; description: string | null; url: string; isFork: boolean; stargazerCount: number; primaryLanguage: { name: string } | null }> } } } }>('gh', ['api', 'graphql', '-f', `query=${query}`]);66  const nodes = response.data?.user?.pinnedItems?.nodes ?? [];67  return { ok: true, pinned: nodes };68}69 70export async function setPinnedRepos(repoIds?: string[]) {71  const current = await listPinnedRepos();72  const existingIds = new Set(current.pinned.map((r) => r.id));73  for (const existingId of existingIds) {74    try {75      await runCommand('gh', ['api', 'graphql', '-f', `query=mutation { unpinRepository(input: {repositoryId: "${existingId}"}) { repository { name } } }`], undefined);76    } catch {}77  }78  const desiredIds = repoIds ?? [];79  for (const repoId of desiredIds) {80    await runCommand('gh', ['api', 'graphql', '-f', `query=mutation { pinRepository(input: {repositoryId: "${repoId}"}) { repository { name } } }`], undefined);81  }82  await recordAuditEvent({ kind: 'profile.pinned_repos.set', result: { repoIds: desiredIds } });83  return { ok: true, pinned: desiredIds };84}85 86export async function updateRepoMetadata(input: { repo: string; description?: string; homepage?: string; topics?: string[]; visibility?: 'public' | 'private' }) {87  const args = ['api', `repos/${input.repo}`, '--method', 'PATCH'];88  if (input.description !== undefined) args.push('-f', `description=${input.description}`);89  if (input.homepage !== undefined) args.push('-f', `homepage=${input.homepage}`);90  if (input.visibility !== undefined) args.push('-f', `visibility=${input.visibility}`);91  await runCommand('gh', args, undefined);92  if (input.topics && input.topics.length > 0) {93    const topicArgs = ['api', `repos/${input.repo}/topics`, '--method', 'PUT', '-H', 'Accept: application/vnd.github+json'];94    for (const topic of input.topics) {95      topicArgs.push('-F', `names[]=${topic}`);96    }97    await runCommand('gh', topicArgs, undefined);98  }99  await recordAuditEvent({ kind: 'repo.metadata.update', result: input });100  return { ok: true, repo: input.repo };101}102 103export async function triggerQuickdraw(repo?: string) {104  const target = repo ?? 'Delqhi/Delqhi';105  const issue = await runJsonCommand<{ number: number; html_url: string }>('gh', ['issue', 'create', '--repo', target, '--title', 'Quickdraw profile check', '--body', 'Triggering Quickdraw achievement via issue lifecycle.']);106  await runCommand('gh', ['issue', 'close', String(issue.number), '--repo', target, '--comment', 'Closed for Quickdraw verification.'], undefined);107  await recordAuditEvent({ kind: 'achievement.quickdraw.trigger', result: { repo: target, issueNumber: issue.number } });108  return { ok: true, repo: target, issueNumber: issue.number, issueUrl: issue.html_url };109}110 111export async function quickdrawStatus() {112  const issues = await runJsonCommand<Array<{ number: number; state: string; closed_at: string | null }>>('gh', ['issue', 'list', '--repo', 'Delqhi/Delqhi', '--state', 'all', '--limit', '10', '--json', 'number,state,closed_at']);113  const closed = issues.filter((i) => i.state === 'closed' && i.closed_at).length;114  return { ok: true, totalClosed: closed, likelyQuickdraw: closed >= 1 };115}116