@triedotdev/mcp 1.0.138 → 1.0.140

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 (74) hide show
  1. package/README.md +184 -38
  2. package/dist/{autonomy-config-TZ6HF4FA.js → autonomy-config-ZCOSTMPD.js} +2 -2
  3. package/dist/{chunk-X3F5QDER.js → chunk-4O2KRHK4.js} +934 -132
  4. package/dist/chunk-4O2KRHK4.js.map +1 -0
  5. package/dist/{chunk-J5EMP4XW.js → chunk-5KJ4UJOY.js} +9 -4
  6. package/dist/chunk-5KJ4UJOY.js.map +1 -0
  7. package/dist/chunk-62POBLFC.js +1925 -0
  8. package/dist/chunk-62POBLFC.js.map +1 -0
  9. package/dist/{chunk-GFFUDJMK.js → chunk-75ADWWUF.js} +13 -13
  10. package/dist/chunk-75ADWWUF.js.map +1 -0
  11. package/dist/{chunk-D3AS5LY7.js → chunk-7OJ6JIPL.js} +39 -604
  12. package/dist/chunk-7OJ6JIPL.js.map +1 -0
  13. package/dist/{chunk-3RRXWX3V.js → chunk-AF2APASP.js} +38 -4
  14. package/dist/{chunk-3RRXWX3V.js.map → chunk-AF2APASP.js.map} +1 -1
  15. package/dist/{chunk-QSWUPSLK.js → chunk-FH335WL5.js} +9 -1
  16. package/dist/chunk-FH335WL5.js.map +1 -0
  17. package/dist/{chunk-Y32FM3MR.js → chunk-FPEMP54L.js} +21 -15
  18. package/dist/chunk-FPEMP54L.js.map +1 -0
  19. package/dist/{chunk-EDDT4ZIH.js → chunk-GXF6JOCN.js} +21 -323
  20. package/dist/chunk-GXF6JOCN.js.map +1 -0
  21. package/dist/chunk-LD7ZEFNY.js +132 -0
  22. package/dist/chunk-LD7ZEFNY.js.map +1 -0
  23. package/dist/chunk-NKHO34UZ.js +467 -0
  24. package/dist/chunk-NKHO34UZ.js.map +1 -0
  25. package/dist/{chunk-YOKQ25IW.js → chunk-OQ4A3RDY.js} +14 -14
  26. package/dist/{chunk-6LLH3TBZ.js → chunk-UOSTOLU7.js} +12 -12
  27. package/dist/{chunk-67GSG2ST.js → chunk-XTTZAQWJ.js} +18 -15
  28. package/dist/chunk-XTTZAQWJ.js.map +1 -0
  29. package/dist/{chunk-FOCXXIXY.js → chunk-YEIJW6X6.js} +2 -2
  30. package/dist/chunk-YOJGSRZK.js +216 -0
  31. package/dist/chunk-YOJGSRZK.js.map +1 -0
  32. package/dist/cli/main.js +573 -59
  33. package/dist/cli/main.js.map +1 -1
  34. package/dist/cli/yolo-daemon.js +15 -13
  35. package/dist/cli/yolo-daemon.js.map +1 -1
  36. package/dist/{client-JTU5TRLB.js → client-INNE2GGZ.js} +2 -2
  37. package/dist/{codebase-index-FNJ4GCBE.js → codebase-index-5SEOESWM.js} +3 -3
  38. package/dist/fast-analyzer-AYLZB5TW.js +216 -0
  39. package/dist/fast-analyzer-AYLZB5TW.js.map +1 -0
  40. package/dist/github-ingester-J2ZFYXVE.js +11 -0
  41. package/dist/{goal-manager-6BJQ36AH.js → goal-manager-ZBWKWEML.js} +3 -3
  42. package/dist/{goal-validator-GISXYANK.js → goal-validator-HNXXUCPW.js} +3 -3
  43. package/dist/{graph-X2FMRQLG.js → graph-J4OGTYCO.js} +2 -2
  44. package/dist/{hypothesis-K3KQJOXJ.js → hypothesis-JCUMZKTG.js} +3 -3
  45. package/dist/index.js +1090 -108
  46. package/dist/index.js.map +1 -1
  47. package/dist/{issue-store-BO5OWLJW.js → issue-store-LZWZIGM7.js} +2 -2
  48. package/dist/linear-ingester-JRDQAIAA.js +11 -0
  49. package/dist/linear-ingester-JRDQAIAA.js.map +1 -0
  50. package/dist/{trie-agent-XMSGMD7E.js → trie-agent-M6PHM6UD.js} +10 -10
  51. package/dist/trie-agent-M6PHM6UD.js.map +1 -0
  52. package/package.json +15 -8
  53. package/dist/chunk-67GSG2ST.js.map +0 -1
  54. package/dist/chunk-D3AS5LY7.js.map +0 -1
  55. package/dist/chunk-EDDT4ZIH.js.map +0 -1
  56. package/dist/chunk-GFFUDJMK.js.map +0 -1
  57. package/dist/chunk-J5EMP4XW.js.map +0 -1
  58. package/dist/chunk-QSWUPSLK.js.map +0 -1
  59. package/dist/chunk-X3F5QDER.js.map +0 -1
  60. package/dist/chunk-Y32FM3MR.js.map +0 -1
  61. package/dist/chunk-Z2P4WST6.js +0 -883
  62. package/dist/chunk-Z2P4WST6.js.map +0 -1
  63. /package/dist/{autonomy-config-TZ6HF4FA.js.map → autonomy-config-ZCOSTMPD.js.map} +0 -0
  64. /package/dist/{chunk-YOKQ25IW.js.map → chunk-OQ4A3RDY.js.map} +0 -0
  65. /package/dist/{chunk-6LLH3TBZ.js.map → chunk-UOSTOLU7.js.map} +0 -0
  66. /package/dist/{chunk-FOCXXIXY.js.map → chunk-YEIJW6X6.js.map} +0 -0
  67. /package/dist/{client-JTU5TRLB.js.map → client-INNE2GGZ.js.map} +0 -0
  68. /package/dist/{codebase-index-FNJ4GCBE.js.map → codebase-index-5SEOESWM.js.map} +0 -0
  69. /package/dist/{goal-manager-6BJQ36AH.js.map → github-ingester-J2ZFYXVE.js.map} +0 -0
  70. /package/dist/{goal-validator-GISXYANK.js.map → goal-manager-ZBWKWEML.js.map} +0 -0
  71. /package/dist/{graph-X2FMRQLG.js.map → goal-validator-HNXXUCPW.js.map} +0 -0
  72. /package/dist/{hypothesis-K3KQJOXJ.js.map → graph-J4OGTYCO.js.map} +0 -0
  73. /package/dist/{issue-store-BO5OWLJW.js.map → hypothesis-JCUMZKTG.js.map} +0 -0
  74. /package/dist/{trie-agent-XMSGMD7E.js.map → issue-store-LZWZIGM7.js.map} +0 -0
@@ -0,0 +1,216 @@
1
+ import {
2
+ loadConfig
3
+ } from "./chunk-NKHO34UZ.js";
4
+
5
+ // src/ingest/github-ingester.ts
6
+ import path from "path";
7
+ import { execSync } from "child_process";
8
+ var TICKET_PATTERN = /\b([A-Z]{2,10}-\d+)\b/g;
9
+ var GitHubIngester = class {
10
+ graph;
11
+ constructor(graph) {
12
+ this.graph = graph;
13
+ }
14
+ async getApiToken() {
15
+ const config = await loadConfig();
16
+ return config.apiKeys?.github ?? process.env.GITHUB_TOKEN ?? null;
17
+ }
18
+ getRepoInfo(projectPath) {
19
+ try {
20
+ const url = execSync("git remote get-url origin", {
21
+ cwd: projectPath,
22
+ encoding: "utf-8",
23
+ stdio: ["pipe", "pipe", "pipe"]
24
+ }).trim();
25
+ const sshMatch = url.match(/github\.com[:/]([^/]+)\/([^/.]+)/);
26
+ if (sshMatch) {
27
+ return { owner: sshMatch[1], name: sshMatch[2] };
28
+ }
29
+ const httpsMatch = url.match(/github\.com\/([^/]+)\/([^/.]+)/);
30
+ if (httpsMatch) {
31
+ return { owner: httpsMatch[1], name: httpsMatch[2] };
32
+ }
33
+ return null;
34
+ } catch {
35
+ return null;
36
+ }
37
+ }
38
+ async syncPullRequests(owner, repo, token) {
39
+ const prs = await this.fetchJson(
40
+ `https://api.github.com/repos/${owner}/${repo}/pulls?state=open&per_page=50`,
41
+ token
42
+ );
43
+ let linkedTickets = 0;
44
+ let linkedFiles = 0;
45
+ for (const pr of prs) {
46
+ const filesChanged = await this.fetchPRFiles(owner, repo, pr.number, token);
47
+ const reviewStatus = await this.fetchReviewStatus(owner, repo, pr.number, token);
48
+ const ciStatus = await this.fetchCIStatus(owner, repo, pr.head.ref, token);
49
+ const linkedTicketIds = this.extractTicketIds(pr.title, pr.body);
50
+ const state = pr.draft ? "draft" : pr.state === "open" ? "open" : "closed";
51
+ const data = {
52
+ prNumber: pr.number,
53
+ title: pr.title,
54
+ url: pr.html_url,
55
+ state,
56
+ author: pr.user.login,
57
+ branch: pr.head.ref,
58
+ baseBranch: pr.base.ref,
59
+ isDraft: pr.draft,
60
+ filesChanged,
61
+ linkedTicketIds,
62
+ ciStatus,
63
+ reviewStatus,
64
+ createdAt: pr.created_at,
65
+ updatedAt: pr.updated_at,
66
+ ...pr.merged_at != null && { mergedAt: pr.merged_at }
67
+ };
68
+ const prNodeId = `pr:${pr.number}`;
69
+ const existingNode = await this.graph.getNode("pull-request", prNodeId);
70
+ if (existingNode) {
71
+ await this.graph.updateNode("pull-request", prNodeId, data);
72
+ } else {
73
+ await this.graph.addNode("pull-request", data);
74
+ }
75
+ for (const file of filesChanged) {
76
+ const resolvedPath = path.resolve(this.graph.projectRoot, file);
77
+ const fileNode = await this.graph.getNode("file", resolvedPath);
78
+ if (fileNode) {
79
+ linkedFiles++;
80
+ await this.graph.addEdge(prNodeId, fileNode.id, "affects");
81
+ }
82
+ }
83
+ for (const ticketId of linkedTicketIds) {
84
+ const ticketNodeId = `linear:${ticketId}`;
85
+ const ticketNode = await this.graph.getNode("linear-ticket", ticketNodeId);
86
+ if (ticketNode) {
87
+ linkedTickets++;
88
+ await this.graph.addEdge(ticketNodeId, prNodeId, "implements");
89
+ }
90
+ }
91
+ }
92
+ return { prs: prs.length, linkedTickets, linkedFiles };
93
+ }
94
+ async syncIssues(owner, repo, token) {
95
+ const allItems = await this.fetchJson(
96
+ `https://api.github.com/repos/${owner}/${repo}/issues?state=open&per_page=50`,
97
+ token
98
+ );
99
+ const issues = allItems.filter((item) => !item.pull_request);
100
+ for (const issue of issues) {
101
+ const linkedTicketIds = this.extractTicketIds(issue.title, issue.body);
102
+ const data = {
103
+ issueNumber: issue.number,
104
+ title: issue.title,
105
+ url: issue.html_url,
106
+ state: issue.state,
107
+ labels: issue.labels.map((l) => l.name),
108
+ assignees: issue.assignees.map((a) => a.login),
109
+ body: issue.body ?? "",
110
+ linkedTicketIds,
111
+ createdAt: issue.created_at,
112
+ updatedAt: issue.updated_at,
113
+ ...issue.closed_at != null && { closedAt: issue.closed_at }
114
+ };
115
+ const issueNodeId = `gh-issue:${issue.number}`;
116
+ const existingNode = await this.graph.getNode("github-issue", issueNodeId);
117
+ if (existingNode) {
118
+ await this.graph.updateNode("github-issue", issueNodeId, data);
119
+ } else {
120
+ await this.graph.addNode("github-issue", data);
121
+ }
122
+ for (const ticketId of linkedTicketIds) {
123
+ const ticketNodeId = `linear:${ticketId}`;
124
+ const ticketNode = await this.graph.getNode("linear-ticket", ticketNodeId);
125
+ if (ticketNode) {
126
+ await this.graph.addEdge(issueNodeId, ticketNodeId, "relatedTo");
127
+ }
128
+ }
129
+ }
130
+ return { issues: issues.length };
131
+ }
132
+ async fetchPRFiles(owner, repo, prNumber, token) {
133
+ try {
134
+ const files = await this.fetchJson(
135
+ `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/files?per_page=100`,
136
+ token
137
+ );
138
+ return files.map((f) => f.filename);
139
+ } catch {
140
+ return [];
141
+ }
142
+ }
143
+ async fetchReviewStatus(owner, repo, prNumber, token) {
144
+ try {
145
+ const reviews = await this.fetchJson(
146
+ `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/reviews`,
147
+ token
148
+ );
149
+ if (reviews.length === 0) return "none";
150
+ const states = reviews.map((r) => r.state);
151
+ if (states.includes("CHANGES_REQUESTED")) return "changes_requested";
152
+ if (states.includes("APPROVED")) return "approved";
153
+ return "pending";
154
+ } catch {
155
+ return "none";
156
+ }
157
+ }
158
+ async fetchCIStatus(owner, repo, ref, token) {
159
+ try {
160
+ const status = await this.fetchJson(
161
+ `https://api.github.com/repos/${owner}/${repo}/commits/${ref}/status`,
162
+ token
163
+ );
164
+ switch (status.state) {
165
+ case "success":
166
+ return "passing";
167
+ case "failure":
168
+ case "error":
169
+ return "failing";
170
+ case "pending":
171
+ return "pending";
172
+ default:
173
+ return "unknown";
174
+ }
175
+ } catch {
176
+ return "unknown";
177
+ }
178
+ }
179
+ extractTicketIds(title, body) {
180
+ const text = `${title} ${body ?? ""}`;
181
+ const matches = text.match(TICKET_PATTERN);
182
+ return matches ? [...new Set(matches)] : [];
183
+ }
184
+ async fetchJson(url, token) {
185
+ const response = await fetch(url, {
186
+ headers: {
187
+ "Accept": "application/vnd.github.v3+json",
188
+ "Authorization": `Bearer ${token}`,
189
+ "User-Agent": "trie-agents",
190
+ "X-GitHub-Api-Version": "2022-11-28"
191
+ }
192
+ });
193
+ if (response.status === 401) {
194
+ throw new Error(
195
+ "GitHub token is invalid or expired. Set a valid token:\n \u2022 Environment: GITHUB_TOKEN=ghp_...\n \u2022 Config: trie config \u2192 API Keys \u2192 GitHub"
196
+ );
197
+ }
198
+ if (response.status === 403) {
199
+ const resetHeader = response.headers.get("X-RateLimit-Reset");
200
+ const resetTime = resetHeader ? new Date(parseInt(resetHeader, 10) * 1e3).toLocaleTimeString() : "unknown";
201
+ throw new Error(`GitHub API rate limit exceeded. Resets at ${resetTime}.`);
202
+ }
203
+ if (response.status === 404) {
204
+ throw new Error("Repository not found or token lacks access. Ensure the token has `repo` scope.");
205
+ }
206
+ if (!response.ok) {
207
+ throw new Error(`GitHub API error ${response.status}: ${response.statusText}`);
208
+ }
209
+ return await response.json();
210
+ }
211
+ };
212
+
213
+ export {
214
+ GitHubIngester
215
+ };
216
+ //# sourceMappingURL=chunk-YOJGSRZK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ingest/github-ingester.ts"],"sourcesContent":["import path from 'node:path';\nimport { execSync } from 'node:child_process';\nimport { loadConfig } from '../config/loader.js';\nimport { ContextGraph } from '../context/graph.js';\nimport type { PullRequestNodeData, GitHubIssueNodeData } from '../context/nodes.js';\n\nconst TICKET_PATTERN = /\\b([A-Z]{2,10}-\\d+)\\b/g;\n\ninterface GitHubPR {\n number: number;\n title: string;\n html_url: string;\n state: string;\n draft: boolean;\n user: { login: string };\n head: { ref: string };\n base: { ref: string };\n body: string | null;\n created_at: string;\n updated_at: string;\n merged_at: string | null;\n}\n\ninterface GitHubFile {\n filename: string;\n}\n\ninterface GitHubReview {\n state: string;\n}\n\ninterface GitHubIssue {\n number: number;\n title: string;\n html_url: string;\n state: string;\n labels: Array<{ name: string }>;\n assignees: Array<{ login: string }>;\n body: string | null;\n pull_request?: unknown;\n created_at: string;\n updated_at: string;\n closed_at: string | null;\n}\n\ninterface GitHubCommitStatus {\n state: string;\n}\n\nexport interface GitHubSyncResult {\n prs: number;\n issues: number;\n linkedTickets: number;\n linkedFiles: number;\n}\n\nexport class GitHubIngester {\n private readonly graph: ContextGraph;\n\n constructor(graph: ContextGraph) {\n this.graph = graph;\n }\n\n async getApiToken(): Promise<string | null> {\n const config = await loadConfig();\n return config.apiKeys?.github ?? process.env.GITHUB_TOKEN ?? null;\n }\n\n getRepoInfo(projectPath: string): { owner: string; name: string } | null {\n try {\n const url = execSync('git remote get-url origin', {\n cwd: projectPath,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n // SSH: git@github.com:owner/repo.git\n const sshMatch = url.match(/github\\.com[:/]([^/]+)\\/([^/.]+)/);\n if (sshMatch) {\n return { owner: sshMatch[1]!, name: sshMatch[2]! };\n }\n\n // HTTPS: https://github.com/owner/repo.git\n const httpsMatch = url.match(/github\\.com\\/([^/]+)\\/([^/.]+)/);\n if (httpsMatch) {\n return { owner: httpsMatch[1]!, name: httpsMatch[2]! };\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n async syncPullRequests(owner: string, repo: string, token: string): Promise<{ prs: number; linkedTickets: number; linkedFiles: number }> {\n const prs = await this.fetchJson<GitHubPR[]>(\n `https://api.github.com/repos/${owner}/${repo}/pulls?state=open&per_page=50`,\n token,\n );\n\n let linkedTickets = 0;\n let linkedFiles = 0;\n\n for (const pr of prs) {\n const filesChanged = await this.fetchPRFiles(owner, repo, pr.number, token);\n const reviewStatus = await this.fetchReviewStatus(owner, repo, pr.number, token);\n const ciStatus = await this.fetchCIStatus(owner, repo, pr.head.ref, token);\n const linkedTicketIds = this.extractTicketIds(pr.title, pr.body);\n\n const state: PullRequestNodeData['state'] = pr.draft ? 'draft' : pr.state === 'open' ? 'open' : 'closed';\n\n const data: PullRequestNodeData = {\n prNumber: pr.number,\n title: pr.title,\n url: pr.html_url,\n state,\n author: pr.user.login,\n branch: pr.head.ref,\n baseBranch: pr.base.ref,\n isDraft: pr.draft,\n filesChanged,\n linkedTicketIds,\n ciStatus,\n reviewStatus,\n createdAt: pr.created_at,\n updatedAt: pr.updated_at,\n ...(pr.merged_at != null && { mergedAt: pr.merged_at }),\n };\n\n const prNodeId = `pr:${pr.number}`;\n\n const existingNode = await this.graph.getNode('pull-request', prNodeId);\n if (existingNode) {\n await this.graph.updateNode('pull-request', prNodeId, data);\n } else {\n await this.graph.addNode('pull-request', data);\n }\n\n // Link PR to files it touches (file node IDs are normalized absolute paths)\n for (const file of filesChanged) {\n const resolvedPath = path.resolve(this.graph.projectRoot, file);\n const fileNode = await this.graph.getNode('file', resolvedPath);\n if (fileNode) {\n linkedFiles++;\n await this.graph.addEdge(prNodeId, fileNode.id, 'affects');\n }\n }\n\n // Link Linear tickets to this PR\n for (const ticketId of linkedTicketIds) {\n const ticketNodeId = `linear:${ticketId}`;\n const ticketNode = await this.graph.getNode('linear-ticket', ticketNodeId);\n if (ticketNode) {\n linkedTickets++;\n await this.graph.addEdge(ticketNodeId, prNodeId, 'implements');\n }\n }\n }\n\n return { prs: prs.length, linkedTickets, linkedFiles };\n }\n\n async syncIssues(owner: string, repo: string, token: string): Promise<{ issues: number }> {\n const allItems = await this.fetchJson<GitHubIssue[]>(\n `https://api.github.com/repos/${owner}/${repo}/issues?state=open&per_page=50`,\n token,\n );\n\n // GitHub returns PRs in the issues endpoint — filter them out\n const issues = allItems.filter(item => !item.pull_request);\n\n for (const issue of issues) {\n const linkedTicketIds = this.extractTicketIds(issue.title, issue.body);\n\n const data: GitHubIssueNodeData = {\n issueNumber: issue.number,\n title: issue.title,\n url: issue.html_url,\n state: issue.state as 'open' | 'closed',\n labels: issue.labels.map(l => l.name),\n assignees: issue.assignees.map(a => a.login),\n body: issue.body ?? '',\n linkedTicketIds,\n createdAt: issue.created_at,\n updatedAt: issue.updated_at,\n ...(issue.closed_at != null && { closedAt: issue.closed_at }),\n };\n\n const issueNodeId = `gh-issue:${issue.number}`;\n\n const existingNode = await this.graph.getNode('github-issue', issueNodeId);\n if (existingNode) {\n await this.graph.updateNode('github-issue', issueNodeId, data);\n } else {\n await this.graph.addNode('github-issue', data);\n }\n\n // Link to related Linear tickets\n for (const ticketId of linkedTicketIds) {\n const ticketNodeId = `linear:${ticketId}`;\n const ticketNode = await this.graph.getNode('linear-ticket', ticketNodeId);\n if (ticketNode) {\n await this.graph.addEdge(issueNodeId, ticketNodeId, 'relatedTo');\n }\n }\n }\n\n return { issues: issues.length };\n }\n\n private async fetchPRFiles(owner: string, repo: string, prNumber: number, token: string): Promise<string[]> {\n try {\n const files = await this.fetchJson<GitHubFile[]>(\n `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/files?per_page=100`,\n token,\n );\n return files.map(f => f.filename);\n } catch {\n return [];\n }\n }\n\n private async fetchReviewStatus(\n owner: string,\n repo: string,\n prNumber: number,\n token: string,\n ): Promise<PullRequestNodeData['reviewStatus']> {\n try {\n const reviews = await this.fetchJson<GitHubReview[]>(\n `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/reviews`,\n token,\n );\n if (reviews.length === 0) return 'none';\n\n const states = reviews.map(r => r.state);\n if (states.includes('CHANGES_REQUESTED')) return 'changes_requested';\n if (states.includes('APPROVED')) return 'approved';\n return 'pending';\n } catch {\n return 'none';\n }\n }\n\n private async fetchCIStatus(\n owner: string,\n repo: string,\n ref: string,\n token: string,\n ): Promise<PullRequestNodeData['ciStatus']> {\n try {\n const status = await this.fetchJson<GitHubCommitStatus>(\n `https://api.github.com/repos/${owner}/${repo}/commits/${ref}/status`,\n token,\n );\n switch (status.state) {\n case 'success': return 'passing';\n case 'failure': case 'error': return 'failing';\n case 'pending': return 'pending';\n default: return 'unknown';\n }\n } catch {\n return 'unknown';\n }\n }\n\n private extractTicketIds(title: string, body: string | null): string[] {\n const text = `${title} ${body ?? ''}`;\n const matches = text.match(TICKET_PATTERN);\n return matches ? [...new Set(matches)] : [];\n }\n\n private async fetchJson<T>(url: string, token: string): Promise<T> {\n const response = await fetch(url, {\n headers: {\n 'Accept': 'application/vnd.github.v3+json',\n 'Authorization': `Bearer ${token}`,\n 'User-Agent': 'trie-agents',\n 'X-GitHub-Api-Version': '2022-11-28',\n },\n });\n\n if (response.status === 401) {\n throw new Error(\n 'GitHub token is invalid or expired. Set a valid token:\\n' +\n ' • Environment: GITHUB_TOKEN=ghp_...\\n' +\n ' • Config: trie config → API Keys → GitHub',\n );\n }\n\n if (response.status === 403) {\n const resetHeader = response.headers.get('X-RateLimit-Reset');\n const resetTime = resetHeader\n ? new Date(parseInt(resetHeader, 10) * 1000).toLocaleTimeString()\n : 'unknown';\n throw new Error(`GitHub API rate limit exceeded. Resets at ${resetTime}.`);\n }\n\n if (response.status === 404) {\n throw new Error('Repository not found or token lacks access. Ensure the token has `repo` scope.');\n }\n\n if (!response.ok) {\n throw new Error(`GitHub API error ${response.status}: ${response.statusText}`);\n }\n\n return (await response.json()) as T;\n }\n}\n"],"mappings":"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","names":[]}