{"version":3,"sources":["../src/tools/github.ts"],"names":["tool","z"],"mappings":"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","file":"chunk-LCGXWJ25.cjs","sourcesContent":["import { tool } from '@strands-agents/sdk'\nimport { z } from 'zod'\n\n// ────────────────────────────────────────────────────────────────────\n// use_github — GraphQL-first GitHub tool (mirrors devduck's use_github)\n// ────────────────────────────────────────────────────────────────────\n// One tool, any GraphQL query or mutation. REST helpers below are thin\n// wrappers that build GraphQL under the hood so there's exactly one\n// auth + transport path to maintain.\n\nfunction getToken(): string | null {\n  try {\n    const raw = localStorage.getItem('careless-v2-settings')\n    return raw ? JSON.parse(raw).githubToken : null\n  } catch {\n    return null\n  }\n}\n\ninterface GraphQLResult {\n  status: 'success' | 'error'\n  data?: unknown\n  errors?: unknown\n  rate_limit?: { remaining: number; limit: number; reset_at?: string }\n  message?: string\n}\n\nasync function graphql(\n  query: string,\n  variables?: Record<string, unknown>,\n): Promise<GraphQLResult> {\n  const token = getToken()\n  if (!token) {\n    return {\n      status: 'error',\n      message:\n        'GITHUB_TOKEN missing. Set githubToken in Settings (Settings > Credentials).',\n    }\n  }\n\n  try {\n    const res = await fetch('https://api.github.com/graphql', {\n      method: 'POST',\n      headers: {\n        Authorization: `Bearer ${token}`,\n        'Content-Type': 'application/json',\n        Accept: 'application/vnd.github+json',\n      },\n      body: JSON.stringify({ query, variables: variables || {} }),\n    })\n\n    const rateRemaining = res.headers.get('x-ratelimit-remaining')\n    const rateLimit = res.headers.get('x-ratelimit-limit')\n    const rateReset = res.headers.get('x-ratelimit-reset')\n    const rate_limit = rateRemaining\n      ? {\n          remaining: Number(rateRemaining),\n          limit: Number(rateLimit || 0),\n          reset_at: rateReset\n            ? new Date(Number(rateReset) * 1000).toISOString()\n            : undefined,\n        }\n      : undefined\n\n    if (!res.ok) {\n      const text = await res.text().catch(() => '')\n      return {\n        status: 'error',\n        message: `HTTP ${res.status}: ${text.slice(0, 500)}`,\n        rate_limit,\n      }\n    }\n\n    const body = await res.json()\n    if (body.errors) {\n      return { status: 'error', errors: body.errors, rate_limit }\n    }\n    return { status: 'success', data: body.data, rate_limit }\n  } catch (err: unknown) {\n    return { status: 'error', message: (err as Error).message }\n  }\n}\n\n// Validate query_type hint vs. the query text (lightweight — GitHub's\n// GraphQL server is authoritative).\nfunction validateQueryType(\n  queryType: 'query' | 'mutation',\n  query: string,\n): string | null {\n  const trimmed = query.trim().toLowerCase()\n  if (queryType === 'mutation' && !trimmed.startsWith('mutation')) {\n    return \"query_type='mutation' but query does not start with 'mutation'\"\n  }\n  if (\n    queryType === 'query' &&\n    trimmed.startsWith('mutation')\n  ) {\n    return \"query_type='query' but query starts with 'mutation'\"\n  }\n  return null\n}\n\n// ────────────────────────────────────────────────────────────────────\n// The universal tool\n// ────────────────────────────────────────────────────────────────────\n\nexport const useGithubTool = tool({\n  name: 'use_github',\n  description:\n    'Execute any GitHub GraphQL query or mutation. Supports the full v4 schema: ' +\n    'repositories, issues, PRs, users, orgs, projects, commits, branches, security. ' +\n    'Requires githubToken in Settings. Returns data + rate limit info.',\n  inputSchema: z.object({\n    query_type: z\n      .enum(['query', 'mutation'])\n      .describe('Type of GraphQL operation'),\n    query: z.string().describe('The GraphQL query or mutation string'),\n    variables: z\n      .record(z.string(), z.any())\n      .optional()\n      .describe('Optional variables for the query'),\n    label: z\n      .string()\n      .optional()\n      .describe('Human-readable description of the operation (for logs)'),\n  }),\n  callback: async ({ query_type, query, variables, label }) => {\n    const validationError = validateQueryType(query_type, query)\n    if (validationError) {\n      return JSON.stringify({ status: 'error', message: validationError })\n    }\n\n    if (label) {\n      // eslint-disable-next-line no-console\n      console.log(`[use_github] ${query_type}: ${label}`)\n    }\n\n    const result = await graphql(query, variables)\n    return JSON.stringify(result)\n  },\n})\n\n// ────────────────────────────────────────────────────────────────────\n// Thin convenience wrappers (backward compat with existing callers)\n// All three build GraphQL under the hood — one auth path, one transport.\n// ────────────────────────────────────────────────────────────────────\n\nexport const githubSearchRepoTool = tool({\n  name: 'github_search_repos',\n  description:\n    'Search GitHub repositories (convenience wrapper on use_github).',\n  inputSchema: z.object({\n    query: z.string(),\n    limit: z.number().optional(),\n  }),\n  callback: async ({ query, limit }) => {\n    const gql = `\n      query($q: String!, $first: Int!) {\n        search(query: $q, type: REPOSITORY, first: $first) {\n          repositoryCount\n          nodes {\n            ... on Repository {\n              nameWithOwner\n              description\n              stargazerCount\n              forkCount\n              primaryLanguage { name }\n              url\n              updatedAt\n            }\n          }\n        }\n      }`\n    const result = await graphql(gql, { q: query, first: limit || 5 })\n    if (result.status !== 'success') return JSON.stringify(result)\n\n    type SearchNode = {\n      nameWithOwner: string\n      description: string | null\n      stargazerCount: number\n      forkCount: number\n      primaryLanguage: { name: string } | null\n      url: string\n      updatedAt: string\n    }\n    const search = (result.data as { search?: { repositoryCount: number; nodes: SearchNode[] } })\n      ?.search\n    const results =\n      search?.nodes.map((r) => ({\n        name: r.nameWithOwner,\n        description: r.description,\n        stars: r.stargazerCount,\n        forks: r.forkCount,\n        language: r.primaryLanguage?.name,\n        url: r.url,\n        updated_at: r.updatedAt,\n      })) || []\n    return JSON.stringify({\n      status: 'success',\n      total: search?.repositoryCount || 0,\n      results,\n      rate_limit: result.rate_limit,\n    })\n  },\n})\n\nexport const githubGetRepoTool = tool({\n  name: 'github_get_repo',\n  description:\n    'Get GitHub repo info (convenience wrapper on use_github). Includes open issue + PR counts.',\n  inputSchema: z.object({ owner: z.string(), name: z.string() }),\n  callback: async ({ owner, name }) => {\n    const gql = `\n      query($owner: String!, $name: String!) {\n        repository(owner: $owner, name: $name) {\n          nameWithOwner\n          description\n          stargazerCount\n          forkCount\n          primaryLanguage { name }\n          url\n          updatedAt\n          pushedAt\n          isArchived\n          isFork\n          defaultBranchRef { name }\n          issues(states: OPEN) { totalCount }\n          pullRequests(states: OPEN) { totalCount }\n          licenseInfo { spdxId }\n          diskUsage\n        }\n      }`\n    const result = await graphql(gql, { owner, name })\n    if (result.status !== 'success') return JSON.stringify(result)\n\n    type Repo = {\n      nameWithOwner: string\n      description: string | null\n      stargazerCount: number\n      forkCount: number\n      primaryLanguage: { name: string } | null\n      url: string\n      updatedAt: string\n      pushedAt: string\n      isArchived: boolean\n      isFork: boolean\n      defaultBranchRef: { name: string } | null\n      issues: { totalCount: number }\n      pullRequests: { totalCount: number }\n      licenseInfo: { spdxId: string } | null\n      diskUsage: number\n    }\n    const r = (result.data as { repository: Repo | null })?.repository\n    if (!r) {\n      return JSON.stringify({\n        status: 'error',\n        message: `Repo not found: ${owner}/${name}`,\n      })\n    }\n    return JSON.stringify({\n      status: 'success',\n      name: r.nameWithOwner,\n      description: r.description,\n      stars: r.stargazerCount,\n      forks: r.forkCount,\n      language: r.primaryLanguage?.name,\n      url: r.url,\n      updated_at: r.updatedAt,\n      pushed_at: r.pushedAt,\n      archived: r.isArchived,\n      fork: r.isFork,\n      default_branch: r.defaultBranchRef?.name,\n      open_issues: r.issues.totalCount,\n      open_prs: r.pullRequests.totalCount,\n      license: r.licenseInfo?.spdxId,\n      disk_usage_kb: r.diskUsage,\n      rate_limit: result.rate_limit,\n    })\n  },\n})\n\nexport const githubGetFileTool = tool({\n  name: 'github_get_file',\n  description:\n    'Fetch a file from a GitHub repo, decoded. Uses GraphQL object/blob expression.',\n  inputSchema: z.object({\n    owner: z.string(),\n    name: z.string(),\n    path: z.string(),\n    branch: z.string().optional(),\n  }),\n  callback: async ({ owner, name, path, branch }) => {\n    // expression: \"<ref>:<path>\" — ref defaults to HEAD when omitted\n    const expression = `${branch || 'HEAD'}:${path}`\n    const gql = `\n      query($owner: String!, $name: String!, $expr: String!) {\n        repository(owner: $owner, name: $name) {\n          object(expression: $expr) {\n            ... on Blob {\n              text\n              byteSize\n              isBinary\n              oid\n            }\n          }\n        }\n      }`\n    const result = await graphql(gql, { owner, name, expr: expression })\n    if (result.status !== 'success') return JSON.stringify(result)\n\n    type Blob = {\n      text: string | null\n      byteSize: number\n      isBinary: boolean\n      oid: string\n    }\n    const obj = (\n      result.data as { repository: { object: Blob | null } | null }\n    )?.repository?.object\n    if (!obj) {\n      return JSON.stringify({\n        status: 'error',\n        message: `File not found: ${owner}/${name}:${expression}`,\n      })\n    }\n    if (obj.isBinary) {\n      return JSON.stringify({\n        status: 'error',\n        message: `Binary file (${obj.byteSize} bytes) — GraphQL can't return bytes. Use raw.githubusercontent.com instead.`,\n        oid: obj.oid,\n      })\n    }\n    return JSON.stringify({\n      status: 'success',\n      path,\n      size: obj.byteSize,\n      oid: obj.oid,\n      content: (obj.text || '').slice(0, 20000),\n      rate_limit: result.rate_limit,\n    })\n  },\n})\n\nexport const GITHUB_TOOLS = [\n  useGithubTool,\n  githubSearchRepoTool,\n  githubGetRepoTool,\n  githubGetFileTool,\n]\n"]}