@loopstack/github-oauth-example 0.1.1 → 0.2.0
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/dist/tools/authenticate-github-task.tool.d.ts +9 -8
- package/dist/tools/authenticate-github-task.tool.d.ts.map +1 -1
- package/dist/tools/authenticate-github-task.tool.js +30 -62
- package/dist/tools/authenticate-github-task.tool.js.map +1 -1
- package/dist/workflows/github-agent.ui.yaml +16 -0
- package/dist/workflows/github-agent.workflow.d.ts +14 -13
- package/dist/workflows/github-agent.workflow.d.ts.map +1 -1
- package/dist/workflows/github-agent.workflow.js +155 -71
- package/dist/workflows/github-agent.workflow.js.map +1 -1
- package/dist/workflows/github-repos-overview.ui.yaml +17 -0
- package/dist/workflows/github-repos-overview.workflow.d.ts +77 -87
- package/dist/workflows/github-repos-overview.workflow.d.ts.map +1 -1
- package/dist/workflows/github-repos-overview.workflow.js +177 -228
- package/dist/workflows/github-repos-overview.workflow.js.map +1 -1
- package/dist/workflows/templates/repoOverview.md +81 -0
- package/dist/workflows/templates/systemMessage.md +23 -0
- package/package.json +7 -7
- package/src/tools/authenticate-github-task.tool.ts +34 -82
- package/src/workflows/__tests__/github-repos-overview-workflow.spec.ts +105 -249
- package/src/workflows/github-agent.ui.yaml +16 -0
- package/src/workflows/github-agent.workflow.ts +109 -27
- package/src/workflows/github-repos-overview.ui.yaml +17 -0
- package/src/workflows/github-repos-overview.workflow.ts +257 -215
- package/src/workflows/templates/repoOverview.md +81 -0
- package/src/workflows/templates/systemMessage.md +23 -0
- package/dist/workflows/github-agent.workflow.yaml +0 -154
- package/dist/workflows/github-repos-overview.workflow.yaml +0 -249
- package/src/workflows/github-agent.workflow.yaml +0 -154
- package/src/workflows/github-repos-overview.workflow.yaml +0 -249
|
@@ -1,254 +1,296 @@
|
|
|
1
|
-
import { Injectable } from '@nestjs/common';
|
|
2
1
|
import { z } from 'zod';
|
|
3
2
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
BaseWorkflow,
|
|
4
|
+
CallbackSchema,
|
|
5
|
+
Final,
|
|
6
|
+
Guard,
|
|
7
|
+
Initial,
|
|
7
8
|
InjectTool,
|
|
8
9
|
InjectWorkflow,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
State,
|
|
10
|
+
ToolResult,
|
|
11
|
+
Transition,
|
|
12
12
|
Workflow,
|
|
13
|
-
WorkflowInterface,
|
|
14
13
|
} from '@loopstack/common';
|
|
15
|
-
import {
|
|
16
|
-
import { CreateChatMessage } from '@loopstack/create-chat-message-tool';
|
|
14
|
+
import { LinkDocument, MarkdownDocument } from '@loopstack/core';
|
|
17
15
|
import {
|
|
18
|
-
GitHubCreateIssueCommentTool,
|
|
19
|
-
GitHubCreateIssueTool,
|
|
20
|
-
GitHubCreateOrUpdateFileTool,
|
|
21
|
-
GitHubCreatePullRequestTool,
|
|
22
|
-
GitHubCreateRepoTool,
|
|
23
16
|
GitHubGetAuthenticatedUserTool,
|
|
24
|
-
GitHubGetCommitTool,
|
|
25
|
-
GitHubGetFileContentTool,
|
|
26
|
-
GitHubGetIssueTool,
|
|
27
|
-
GitHubGetPullRequestTool,
|
|
28
17
|
GitHubGetRepoTool,
|
|
29
|
-
GitHubGetWorkflowRunTool,
|
|
30
18
|
GitHubListBranchesTool,
|
|
31
19
|
GitHubListDirectoryTool,
|
|
32
20
|
GitHubListIssuesTool,
|
|
33
|
-
GitHubListPrReviewsTool,
|
|
34
21
|
GitHubListPullRequestsTool,
|
|
35
|
-
GitHubListReposTool,
|
|
36
22
|
GitHubListUserOrgsTool,
|
|
37
23
|
GitHubListWorkflowRunsTool,
|
|
38
|
-
GitHubMergePullRequestTool,
|
|
39
24
|
GitHubSearchCodeTool,
|
|
40
|
-
GitHubSearchIssuesTool,
|
|
41
|
-
GitHubSearchReposTool,
|
|
42
|
-
GitHubTriggerWorkflowTool,
|
|
43
25
|
} from '@loopstack/github-module';
|
|
44
26
|
import { OAuthWorkflow } from '@loopstack/oauth-module';
|
|
45
27
|
|
|
46
|
-
|
|
28
|
+
interface GitHubUserResult {
|
|
29
|
+
error?: string;
|
|
30
|
+
user?: { login: string; name: string | null; htmlUrl: string; publicRepos: number };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface GitHubOrgsResult {
|
|
34
|
+
orgs: Array<{ login: string; description: string | null }>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface GitHubRepoResult {
|
|
38
|
+
repo: {
|
|
39
|
+
fullName: string;
|
|
40
|
+
description: string | null;
|
|
41
|
+
language: string | null;
|
|
42
|
+
stars: number;
|
|
43
|
+
forks: number;
|
|
44
|
+
openIssues: number;
|
|
45
|
+
defaultBranch: string;
|
|
46
|
+
htmlUrl: string;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface GitHubBranchesResult {
|
|
51
|
+
branches: Array<{ name: string; protected: boolean }>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface GitHubIssuesResult {
|
|
55
|
+
issues: Array<{ number: number; title: string; state: string; user: string; htmlUrl: string }>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interface GitHubPullRequestsResult {
|
|
59
|
+
pullRequests: Array<{
|
|
60
|
+
number: number;
|
|
61
|
+
title: string;
|
|
62
|
+
state: string;
|
|
63
|
+
user: string;
|
|
64
|
+
draft: boolean;
|
|
65
|
+
htmlUrl: string;
|
|
66
|
+
}>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface GitHubDirectoryResult {
|
|
70
|
+
entries: Array<{ name: string; type: string; path: string }>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
interface GitHubWorkflowRunsResult {
|
|
74
|
+
totalCount: number;
|
|
75
|
+
runs: Array<{
|
|
76
|
+
id: number;
|
|
77
|
+
name: string;
|
|
78
|
+
status: string;
|
|
79
|
+
conclusion: string | null;
|
|
80
|
+
htmlUrl: string;
|
|
81
|
+
}>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
interface GitHubSearchCodeResult {
|
|
85
|
+
totalCount: number;
|
|
86
|
+
results: Array<{ name: string; path: string; repository: string }>;
|
|
87
|
+
}
|
|
88
|
+
|
|
47
89
|
@Workflow({
|
|
48
|
-
|
|
90
|
+
uiConfig: __dirname + '/github-repos-overview.ui.yaml',
|
|
91
|
+
schema: z
|
|
92
|
+
.object({
|
|
93
|
+
owner: z.string().default('octocat'),
|
|
94
|
+
repo: z.string().default('Hello-World'),
|
|
95
|
+
})
|
|
96
|
+
.strict(),
|
|
49
97
|
})
|
|
50
|
-
export class GitHubReposOverviewWorkflow
|
|
51
|
-
//
|
|
52
|
-
@InjectTool() private task: Task;
|
|
53
|
-
@InjectTool() private createDocument: CreateDocument;
|
|
54
|
-
@InjectTool() private createChatMessage: CreateChatMessage;
|
|
55
|
-
|
|
56
|
-
// GitHub — Users
|
|
98
|
+
export class GitHubReposOverviewWorkflow extends BaseWorkflow<{ owner: string; repo: string }> {
|
|
99
|
+
// GitHub tools
|
|
57
100
|
@InjectTool() private gitHubGetAuthenticatedUser: GitHubGetAuthenticatedUserTool;
|
|
58
101
|
@InjectTool() private gitHubListUserOrgs: GitHubListUserOrgsTool;
|
|
59
|
-
|
|
60
|
-
// GitHub — Repos
|
|
61
|
-
@InjectTool() private gitHubListRepos: GitHubListReposTool;
|
|
62
102
|
@InjectTool() private gitHubGetRepo: GitHubGetRepoTool;
|
|
63
|
-
@InjectTool() private gitHubCreateRepo: GitHubCreateRepoTool;
|
|
64
103
|
@InjectTool() private gitHubListBranches: GitHubListBranchesTool;
|
|
65
|
-
|
|
66
|
-
// GitHub — Issues
|
|
67
104
|
@InjectTool() private gitHubListIssues: GitHubListIssuesTool;
|
|
68
|
-
@InjectTool() private gitHubGetIssue: GitHubGetIssueTool;
|
|
69
|
-
@InjectTool() private gitHubCreateIssue: GitHubCreateIssueTool;
|
|
70
|
-
@InjectTool() private gitHubCreateIssueComment: GitHubCreateIssueCommentTool;
|
|
71
|
-
|
|
72
|
-
// GitHub — Pull Requests
|
|
73
105
|
@InjectTool() private gitHubListPullRequests: GitHubListPullRequestsTool;
|
|
74
|
-
@InjectTool() private gitHubGetPullRequest: GitHubGetPullRequestTool;
|
|
75
|
-
@InjectTool() private gitHubCreatePullRequest: GitHubCreatePullRequestTool;
|
|
76
|
-
@InjectTool() private gitHubMergePullRequest: GitHubMergePullRequestTool;
|
|
77
|
-
@InjectTool() private gitHubListPrReviews: GitHubListPrReviewsTool;
|
|
78
|
-
|
|
79
|
-
// GitHub — Content
|
|
80
|
-
@InjectTool() private gitHubGetFileContent: GitHubGetFileContentTool;
|
|
81
|
-
@InjectTool() private gitHubCreateOrUpdateFile: GitHubCreateOrUpdateFileTool;
|
|
82
106
|
@InjectTool() private gitHubListDirectory: GitHubListDirectoryTool;
|
|
83
|
-
@InjectTool() private gitHubGetCommit: GitHubGetCommitTool;
|
|
84
|
-
|
|
85
|
-
// GitHub — Actions
|
|
86
107
|
@InjectTool() private gitHubListWorkflowRuns: GitHubListWorkflowRunsTool;
|
|
87
|
-
@InjectTool() private gitHubTriggerWorkflow: GitHubTriggerWorkflowTool;
|
|
88
|
-
@InjectTool() private gitHubGetWorkflowRun: GitHubGetWorkflowRunTool;
|
|
89
|
-
|
|
90
|
-
// GitHub — Search
|
|
91
108
|
@InjectTool() private gitHubSearchCode: GitHubSearchCodeTool;
|
|
92
|
-
@InjectTool() private gitHubSearchRepos: GitHubSearchReposTool;
|
|
93
|
-
@InjectTool() private gitHubSearchIssues: GitHubSearchIssuesTool;
|
|
94
|
-
|
|
95
|
-
// Documents
|
|
96
|
-
@InjectDocument() private linkDocument: LinkDocument;
|
|
97
|
-
@InjectDocument() private markdown: MarkdownDocument;
|
|
98
109
|
|
|
99
110
|
@InjectWorkflow() oAuth: OAuthWorkflow;
|
|
100
111
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
+
owner!: string;
|
|
113
|
+
repo!: string;
|
|
114
|
+
requiresAuthentication?: boolean;
|
|
115
|
+
user?: { login: string; name: string | null; htmlUrl: string; publicRepos: number };
|
|
116
|
+
orgs?: Array<{ login: string; description: string | null }>;
|
|
117
|
+
repoDetails?: {
|
|
118
|
+
fullName: string;
|
|
119
|
+
description: string | null;
|
|
120
|
+
language: string | null;
|
|
121
|
+
stars: number;
|
|
122
|
+
forks: number;
|
|
123
|
+
openIssues: number;
|
|
124
|
+
defaultBranch: string;
|
|
125
|
+
htmlUrl: string;
|
|
112
126
|
};
|
|
127
|
+
branches?: Array<{ name: string; protected: boolean }>;
|
|
128
|
+
issues?: Array<{ number: number; title: string; state: string; user: string; htmlUrl: string }>;
|
|
129
|
+
pullRequests?: Array<{
|
|
130
|
+
number: number;
|
|
131
|
+
title: string;
|
|
132
|
+
state: string;
|
|
133
|
+
user: string;
|
|
134
|
+
draft: boolean;
|
|
135
|
+
htmlUrl: string;
|
|
136
|
+
}>;
|
|
137
|
+
directoryEntries?: Array<{ name: string; type: string; path: string }>;
|
|
138
|
+
workflowRuns?: Array<{
|
|
139
|
+
id: number;
|
|
140
|
+
name: string;
|
|
141
|
+
status: string;
|
|
142
|
+
conclusion: string | null;
|
|
143
|
+
htmlUrl: string;
|
|
144
|
+
}>;
|
|
145
|
+
searchResults?: Array<{ name: string; path: string; repository: string }>;
|
|
146
|
+
// --- Step 1: Fetch authenticated user ---
|
|
113
147
|
|
|
114
|
-
@
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
z.object({
|
|
155
|
-
name: z.string(),
|
|
156
|
-
protected: z.boolean(),
|
|
157
|
-
}),
|
|
158
|
-
)
|
|
159
|
-
.optional(),
|
|
160
|
-
issues: z
|
|
161
|
-
.array(
|
|
162
|
-
z.object({
|
|
163
|
-
number: z.number(),
|
|
164
|
-
title: z.string(),
|
|
165
|
-
state: z.string(),
|
|
166
|
-
user: z.string(),
|
|
167
|
-
htmlUrl: z.string(),
|
|
168
|
-
}),
|
|
169
|
-
)
|
|
170
|
-
.optional(),
|
|
171
|
-
pullRequests: z
|
|
172
|
-
.array(
|
|
173
|
-
z.object({
|
|
174
|
-
number: z.number(),
|
|
175
|
-
title: z.string(),
|
|
176
|
-
state: z.string(),
|
|
177
|
-
user: z.string(),
|
|
178
|
-
draft: z.boolean(),
|
|
179
|
-
htmlUrl: z.string(),
|
|
180
|
-
}),
|
|
181
|
-
)
|
|
182
|
-
.optional(),
|
|
183
|
-
directoryEntries: z
|
|
184
|
-
.array(
|
|
185
|
-
z.object({
|
|
186
|
-
name: z.string(),
|
|
187
|
-
type: z.string(),
|
|
188
|
-
path: z.string(),
|
|
189
|
-
}),
|
|
190
|
-
)
|
|
191
|
-
.optional(),
|
|
192
|
-
workflowRuns: z
|
|
193
|
-
.array(
|
|
194
|
-
z.object({
|
|
195
|
-
id: z.number(),
|
|
196
|
-
name: z.string(),
|
|
197
|
-
status: z.string(),
|
|
198
|
-
conclusion: z.string().nullable(),
|
|
199
|
-
htmlUrl: z.string(),
|
|
200
|
-
}),
|
|
201
|
-
)
|
|
202
|
-
.optional(),
|
|
203
|
-
searchResults: z
|
|
204
|
-
.array(
|
|
205
|
-
z.object({
|
|
206
|
-
name: z.string(),
|
|
207
|
-
path: z.string(),
|
|
208
|
-
repository: z.string(),
|
|
209
|
-
}),
|
|
210
|
-
)
|
|
211
|
-
.optional(),
|
|
212
|
-
})
|
|
213
|
-
.strict(),
|
|
148
|
+
@Initial({ to: 'user_fetched' })
|
|
149
|
+
async fetchUser(args: { owner: string; repo: string }) {
|
|
150
|
+
this.owner = args.owner;
|
|
151
|
+
this.repo = args.repo;
|
|
152
|
+
const result: ToolResult<GitHubUserResult> = await this.gitHubGetAuthenticatedUser.call({});
|
|
153
|
+
this.requiresAuthentication = result.data!.error === 'unauthorized';
|
|
154
|
+
this.user = result.data!.user;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// If unauthorized -> launch OAuth
|
|
158
|
+
@Transition({ from: 'user_fetched', to: 'awaiting_auth', priority: 10 })
|
|
159
|
+
@Guard('needsAuth')
|
|
160
|
+
async authRequired() {
|
|
161
|
+
const result = await this.oAuth.run(
|
|
162
|
+
{ provider: 'github', scopes: ['repo', 'read:org', 'workflow'] },
|
|
163
|
+
{ alias: 'oAuth', callback: { transition: 'authCompleted' } },
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
await this.repository.save(
|
|
167
|
+
LinkDocument,
|
|
168
|
+
{
|
|
169
|
+
label: 'GitHub authentication required',
|
|
170
|
+
workflowId: result.workflowId,
|
|
171
|
+
embed: true,
|
|
172
|
+
expanded: true,
|
|
173
|
+
},
|
|
174
|
+
{ id: `link_${result.workflowId}` },
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
needsAuth(): boolean {
|
|
179
|
+
return !!this.requiresAuthentication;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Auth completed -> retry from start
|
|
183
|
+
@Transition({
|
|
184
|
+
from: 'awaiting_auth',
|
|
185
|
+
to: 'start',
|
|
186
|
+
wait: true,
|
|
187
|
+
schema: CallbackSchema,
|
|
214
188
|
})
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
189
|
+
async authCompleted(payload: { workflowId: string }) {
|
|
190
|
+
await this.repository.save(
|
|
191
|
+
LinkDocument,
|
|
192
|
+
{
|
|
193
|
+
status: 'success',
|
|
194
|
+
label: 'GitHub authentication completed',
|
|
195
|
+
workflowId: payload.workflowId,
|
|
196
|
+
embed: true,
|
|
197
|
+
expanded: false,
|
|
198
|
+
},
|
|
199
|
+
{ id: `link_${payload.workflowId}` },
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// --- Step 2: Fetch user orgs ---
|
|
204
|
+
|
|
205
|
+
@Transition({ from: 'user_fetched', to: 'orgs_fetched' })
|
|
206
|
+
async fetchOrgs() {
|
|
207
|
+
const result: ToolResult<GitHubOrgsResult> = await this.gitHubListUserOrgs.call({ perPage: 10 });
|
|
208
|
+
this.orgs = result.data!.orgs;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// --- Step 3: Fetch repo details and branches ---
|
|
212
|
+
|
|
213
|
+
@Transition({ from: 'orgs_fetched', to: 'repo_fetched' })
|
|
214
|
+
async fetchRepoDetails() {
|
|
215
|
+
const repoResult: ToolResult<GitHubRepoResult> = await this.gitHubGetRepo.call({
|
|
216
|
+
owner: this.owner,
|
|
217
|
+
repo: this.repo,
|
|
218
|
+
});
|
|
219
|
+
this.repoDetails = repoResult.data!.repo;
|
|
220
|
+
|
|
221
|
+
const branchesResult: ToolResult<GitHubBranchesResult> = await this.gitHubListBranches.call({
|
|
222
|
+
owner: this.owner,
|
|
223
|
+
repo: this.repo,
|
|
224
|
+
});
|
|
225
|
+
this.branches = branchesResult.data!.branches;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// --- Step 4: Fetch issues and PRs ---
|
|
229
|
+
|
|
230
|
+
@Transition({ from: 'repo_fetched', to: 'issues_prs_fetched' })
|
|
231
|
+
async fetchIssuesPrs() {
|
|
232
|
+
const issuesResult: ToolResult<GitHubIssuesResult> = await this.gitHubListIssues.call({
|
|
233
|
+
owner: this.owner,
|
|
234
|
+
repo: this.repo,
|
|
235
|
+
state: 'open',
|
|
236
|
+
perPage: 10,
|
|
237
|
+
});
|
|
238
|
+
this.issues = issuesResult.data!.issues;
|
|
239
|
+
|
|
240
|
+
const prsResult: ToolResult<GitHubPullRequestsResult> = await this.gitHubListPullRequests.call({
|
|
241
|
+
owner: this.owner,
|
|
242
|
+
repo: this.repo,
|
|
243
|
+
state: 'open',
|
|
244
|
+
perPage: 10,
|
|
245
|
+
});
|
|
246
|
+
this.pullRequests = prsResult.data!.pullRequests;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// --- Step 5: Fetch directory listing and workflow runs ---
|
|
250
|
+
|
|
251
|
+
@Transition({ from: 'issues_prs_fetched', to: 'content_actions_fetched' })
|
|
252
|
+
async fetchContentActions() {
|
|
253
|
+
const dirResult: ToolResult<GitHubDirectoryResult> = await this.gitHubListDirectory.call({
|
|
254
|
+
owner: this.owner,
|
|
255
|
+
repo: this.repo,
|
|
256
|
+
});
|
|
257
|
+
this.directoryEntries = dirResult.data!.entries;
|
|
258
|
+
|
|
259
|
+
const runsResult: ToolResult<GitHubWorkflowRunsResult> = await this.gitHubListWorkflowRuns.call({
|
|
260
|
+
owner: this.owner,
|
|
261
|
+
repo: this.repo,
|
|
262
|
+
perPage: 5,
|
|
263
|
+
});
|
|
264
|
+
this.workflowRuns = runsResult.data!.runs;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// --- Step 6: Search code in the repo ---
|
|
268
|
+
|
|
269
|
+
@Transition({ from: 'content_actions_fetched', to: 'search_done' })
|
|
270
|
+
async fetchSearch() {
|
|
271
|
+
const result: ToolResult<GitHubSearchCodeResult> = await this.gitHubSearchCode.call({
|
|
272
|
+
query: `repo:${this.owner}/${this.repo}`,
|
|
273
|
+
perPage: 5,
|
|
274
|
+
});
|
|
275
|
+
this.searchResults = result.data!.results;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// --- Display all results ---
|
|
249
279
|
|
|
250
|
-
@
|
|
251
|
-
|
|
252
|
-
|
|
280
|
+
@Final({ from: 'search_done' })
|
|
281
|
+
async displayResults() {
|
|
282
|
+
await this.repository.save(MarkdownDocument, {
|
|
283
|
+
markdown: this.render(__dirname + '/templates/repoOverview.md', {
|
|
284
|
+
user: this.user,
|
|
285
|
+
orgs: this.orgs,
|
|
286
|
+
repo: this.repoDetails,
|
|
287
|
+
branches: this.branches,
|
|
288
|
+
issues: this.issues,
|
|
289
|
+
pullRequests: this.pullRequests,
|
|
290
|
+
directoryEntries: this.directoryEntries,
|
|
291
|
+
workflowRuns: this.workflowRuns,
|
|
292
|
+
searchResults: this.searchResults,
|
|
293
|
+
}),
|
|
294
|
+
});
|
|
253
295
|
}
|
|
254
296
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
## Authenticated User
|
|
2
|
+
|
|
3
|
+
**{{ user.login }}** {{#if user.name}}({{ user.name }}){{/if}} — {{ user.publicRepos }} public repos
|
|
4
|
+
|
|
5
|
+
{{#if orgs}}
|
|
6
|
+
|
|
7
|
+
### Organizations
|
|
8
|
+
|
|
9
|
+
{{#each orgs}}
|
|
10
|
+
|
|
11
|
+
- **{{ this.login }}** {{#if this.description}}— {{ this.description }}{{/if}}
|
|
12
|
+
{{/each}}
|
|
13
|
+
{{/if}}
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Repository: [{{ repo.fullName }}]({{ repo.htmlUrl }})
|
|
18
|
+
|
|
19
|
+
{{ repo.description }}
|
|
20
|
+
|
|
21
|
+
| Language | Stars | Forks | Open Issues | Default Branch |
|
|
22
|
+
| ------------------- | ---------------- | ---------------- | --------------------- | ------------------------ |
|
|
23
|
+
| {{ repo.language }} | {{ repo.stars }} | {{ repo.forks }} | {{ repo.openIssues }} | {{ repo.defaultBranch }} |
|
|
24
|
+
|
|
25
|
+
### Branches
|
|
26
|
+
|
|
27
|
+
{{#each branches}}
|
|
28
|
+
|
|
29
|
+
- `{{ this.name }}` {{#if this.protected}}(protected){{/if}}
|
|
30
|
+
{{/each}}
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
### Open Issues
|
|
35
|
+
|
|
36
|
+
{{#each issues}}
|
|
37
|
+
|
|
38
|
+
- [#{{ this.number }}]({{ this.htmlUrl }}) {{ this.title }} — @{{ this.user }}
|
|
39
|
+
{{/each}}
|
|
40
|
+
{{#unless issues}}
|
|
41
|
+
No open issues.
|
|
42
|
+
{{/unless}}
|
|
43
|
+
|
|
44
|
+
### Open Pull Requests
|
|
45
|
+
|
|
46
|
+
{{#each pullRequests}}
|
|
47
|
+
|
|
48
|
+
- [#{{ this.number }}]({{ this.htmlUrl }}) {{ this.title }} — @{{ this.user }} {{#if this.draft}}(draft){{/if}}
|
|
49
|
+
{{/each}}
|
|
50
|
+
{{#unless pullRequests}}
|
|
51
|
+
No open pull requests.
|
|
52
|
+
{{/unless}}
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
### Root Directory
|
|
57
|
+
|
|
58
|
+
{{#each directoryEntries}}
|
|
59
|
+
|
|
60
|
+
- {{ this.type }} `{{ this.name }}`
|
|
61
|
+
{{/each}}
|
|
62
|
+
|
|
63
|
+
### Recent Workflow Runs
|
|
64
|
+
|
|
65
|
+
{{#each workflowRuns}}
|
|
66
|
+
|
|
67
|
+
- [{{ this.name }}]({{ this.htmlUrl }}) — {{ this.status }} {{#if this.conclusion}}({{ this.conclusion }}){{/if}}
|
|
68
|
+
{{/each}}
|
|
69
|
+
{{#unless workflowRuns}}
|
|
70
|
+
No workflow runs found.
|
|
71
|
+
{{/unless}}
|
|
72
|
+
|
|
73
|
+
### Code Search Results
|
|
74
|
+
|
|
75
|
+
{{#each searchResults}}
|
|
76
|
+
|
|
77
|
+
- `{{ this.path }}` in {{ this.repository }}
|
|
78
|
+
{{/each}}
|
|
79
|
+
{{#unless searchResults}}
|
|
80
|
+
No code search results.
|
|
81
|
+
{{/unless}}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
You are a helpful GitHub assistant. You have access to the user's
|
|
2
|
+
GitHub account through the tools provided to you.
|
|
3
|
+
|
|
4
|
+
You can help with:
|
|
5
|
+
|
|
6
|
+
- **Repositories**: List repos, get repo details, create repos, list branches
|
|
7
|
+
- **Issues**: List issues, get issue details, create issues, comment on issues
|
|
8
|
+
- **Pull Requests**: List PRs, get PR details, create PRs, merge PRs, list reviews
|
|
9
|
+
- **Code & Content**: Read files, create/update files, browse directories, view commits
|
|
10
|
+
- **Actions (CI/CD)**: List workflow runs, trigger workflows, check run status
|
|
11
|
+
- **Search**: Search code, repositories, and issues across GitHub
|
|
12
|
+
- **Users & Orgs**: Get user profile, list organizations
|
|
13
|
+
|
|
14
|
+
When a tool returns `{ error: "unauthorized" }` or `{ error: "401" }`, call the
|
|
15
|
+
`authenticateGitHub` tool with the required OAuth scopes to let the user sign in.
|
|
16
|
+
After authentication completes, retry the original request.
|
|
17
|
+
|
|
18
|
+
Common scopes: repo, user, workflow, read:org
|
|
19
|
+
|
|
20
|
+
IMPORTANT: When using authenticateGitHub, it must be the ONLY tool call in your response.
|
|
21
|
+
|
|
22
|
+
Be concise and helpful. Format results clearly using markdown.
|
|
23
|
+
When showing repository or issue information, include links where available.
|