@loopstack/github-oauth-example 0.1.1
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/README.md +114 -0
- package/dist/github-example.module.d.ts +3 -0
- package/dist/github-example.module.d.ts.map +1 -0
- package/dist/github-example.module.js +27 -0
- package/dist/github-example.module.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/authenticate-github-task.tool.d.ts +17 -0
- package/dist/tools/authenticate-github-task.tool.d.ts.map +1 -0
- package/dist/tools/authenticate-github-task.tool.js +107 -0
- package/dist/tools/authenticate-github-task.tool.js.map +1 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +18 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/workflows/github-agent.workflow.d.ts +48 -0
- package/dist/workflows/github-agent.workflow.d.ts.map +1 -0
- package/dist/workflows/github-agent.workflow.js +215 -0
- package/dist/workflows/github-agent.workflow.js.map +1 -0
- package/dist/workflows/github-agent.workflow.yaml +154 -0
- package/dist/workflows/github-repos-overview.workflow.d.ts +102 -0
- package/dist/workflows/github-repos-overview.workflow.d.ts.map +1 -0
- package/dist/workflows/github-repos-overview.workflow.js +300 -0
- package/dist/workflows/github-repos-overview.workflow.js.map +1 -0
- package/dist/workflows/github-repos-overview.workflow.yaml +249 -0
- package/dist/workflows/index.d.ts +3 -0
- package/dist/workflows/index.d.ts.map +1 -0
- package/dist/workflows/index.js +19 -0
- package/dist/workflows/index.js.map +1 -0
- package/package.json +80 -0
- package/src/github-example.module.ts +14 -0
- package/src/index.ts +3 -0
- package/src/tools/authenticate-github-task.tool.ts +125 -0
- package/src/tools/index.ts +1 -0
- package/src/workflows/__tests__/github-repos-overview-workflow.spec.ts +725 -0
- package/src/workflows/github-agent.workflow.ts +118 -0
- package/src/workflows/github-agent.workflow.yaml +154 -0
- package/src/workflows/github-repos-overview.workflow.ts +254 -0
- package/src/workflows/github-repos-overview.workflow.yaml +249 -0
- package/src/workflows/index.ts +2 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
title: 'GitHub Repository Overview'
|
|
2
|
+
|
|
3
|
+
description: |
|
|
4
|
+
Comprehensive GitHub example that exercises every GitHub tool.
|
|
5
|
+
Fetches user info, repository details, issues, pull requests, branches,
|
|
6
|
+
directory contents, workflow runs, and search results for a given repository.
|
|
7
|
+
If not authenticated, launches the OAuth sub-workflow and retries.
|
|
8
|
+
|
|
9
|
+
ui:
|
|
10
|
+
form:
|
|
11
|
+
properties:
|
|
12
|
+
owner:
|
|
13
|
+
title: 'Repository Owner'
|
|
14
|
+
placeholder: 'octocat'
|
|
15
|
+
repo:
|
|
16
|
+
title: 'Repository Name'
|
|
17
|
+
placeholder: 'Hello-World'
|
|
18
|
+
|
|
19
|
+
transitions:
|
|
20
|
+
# Step 1: Fetch authenticated user and orgs
|
|
21
|
+
- id: fetch_user
|
|
22
|
+
from: start
|
|
23
|
+
to: user_fetched
|
|
24
|
+
call:
|
|
25
|
+
- tool: gitHubGetAuthenticatedUser
|
|
26
|
+
id: user_fetch
|
|
27
|
+
args: {}
|
|
28
|
+
assign:
|
|
29
|
+
requiresAuthentication: ${{ result.data.error == "unauthorized" }}
|
|
30
|
+
user: ${{ result.data.user }}
|
|
31
|
+
|
|
32
|
+
# If unauthorized -> launch OAuth
|
|
33
|
+
- id: auth_required
|
|
34
|
+
from: user_fetched
|
|
35
|
+
to: awaiting_auth
|
|
36
|
+
if: ${{ state.requiresAuthentication }}
|
|
37
|
+
call:
|
|
38
|
+
- tool: task
|
|
39
|
+
id: launchAuth
|
|
40
|
+
args:
|
|
41
|
+
workflow: oAuth
|
|
42
|
+
args:
|
|
43
|
+
provider: 'github'
|
|
44
|
+
scopes:
|
|
45
|
+
- 'repo'
|
|
46
|
+
- 'read:org'
|
|
47
|
+
- 'workflow'
|
|
48
|
+
callback:
|
|
49
|
+
transition: auth_completed
|
|
50
|
+
|
|
51
|
+
- tool: createDocument
|
|
52
|
+
args:
|
|
53
|
+
id: authStatus
|
|
54
|
+
document: linkDocument
|
|
55
|
+
update:
|
|
56
|
+
content:
|
|
57
|
+
icon: 'LockKeyhole'
|
|
58
|
+
label: 'GitHub authentication required'
|
|
59
|
+
caption: 'Complete sign-in to continue'
|
|
60
|
+
href: '/pipelines/{{ runtime.tools.auth_required.launchAuth.data.pipelineId }}'
|
|
61
|
+
embed: true
|
|
62
|
+
expanded: true
|
|
63
|
+
|
|
64
|
+
# Auth completed -> retry from start
|
|
65
|
+
- id: auth_completed
|
|
66
|
+
from: awaiting_auth
|
|
67
|
+
to: start
|
|
68
|
+
trigger: manual
|
|
69
|
+
call:
|
|
70
|
+
- tool: createDocument
|
|
71
|
+
args:
|
|
72
|
+
id: authStatus
|
|
73
|
+
document: linkDocument
|
|
74
|
+
update:
|
|
75
|
+
content:
|
|
76
|
+
icon: 'ShieldCheck'
|
|
77
|
+
type: 'success'
|
|
78
|
+
label: 'GitHub authentication completed'
|
|
79
|
+
caption: 'You are now authenticated with GitHub.'
|
|
80
|
+
href: '/pipelines/{{ runtime.transition.payload.pipelineId }}'
|
|
81
|
+
|
|
82
|
+
# Step 2: Fetch user orgs
|
|
83
|
+
- id: fetch_orgs
|
|
84
|
+
from: user_fetched
|
|
85
|
+
to: orgs_fetched
|
|
86
|
+
call:
|
|
87
|
+
- tool: gitHubListUserOrgs
|
|
88
|
+
id: orgs_fetch
|
|
89
|
+
args:
|
|
90
|
+
perPage: 10
|
|
91
|
+
assign:
|
|
92
|
+
orgs: ${{ result.data.orgs }}
|
|
93
|
+
|
|
94
|
+
# Step 3: Fetch repo details and branches
|
|
95
|
+
- id: fetch_repo_details
|
|
96
|
+
from: orgs_fetched
|
|
97
|
+
to: repo_fetched
|
|
98
|
+
call:
|
|
99
|
+
- tool: gitHubGetRepo
|
|
100
|
+
id: repo_fetch
|
|
101
|
+
args:
|
|
102
|
+
owner: ${{ args.owner }}
|
|
103
|
+
repo: ${{ args.repo }}
|
|
104
|
+
assign:
|
|
105
|
+
repo: ${{ result.data.repo }}
|
|
106
|
+
|
|
107
|
+
- tool: gitHubListBranches
|
|
108
|
+
id: branches_fetch
|
|
109
|
+
args:
|
|
110
|
+
owner: ${{ args.owner }}
|
|
111
|
+
repo: ${{ args.repo }}
|
|
112
|
+
assign:
|
|
113
|
+
branches: ${{ result.data.branches }}
|
|
114
|
+
|
|
115
|
+
# Step 4: Fetch issues and PRs
|
|
116
|
+
- id: fetch_issues_prs
|
|
117
|
+
from: repo_fetched
|
|
118
|
+
to: issues_prs_fetched
|
|
119
|
+
call:
|
|
120
|
+
- tool: gitHubListIssues
|
|
121
|
+
id: issues_fetch
|
|
122
|
+
args:
|
|
123
|
+
owner: ${{ args.owner }}
|
|
124
|
+
repo: ${{ args.repo }}
|
|
125
|
+
state: 'open'
|
|
126
|
+
perPage: 10
|
|
127
|
+
assign:
|
|
128
|
+
issues: ${{ result.data.issues }}
|
|
129
|
+
|
|
130
|
+
- tool: gitHubListPullRequests
|
|
131
|
+
id: prs_fetch
|
|
132
|
+
args:
|
|
133
|
+
owner: ${{ args.owner }}
|
|
134
|
+
repo: ${{ args.repo }}
|
|
135
|
+
state: 'open'
|
|
136
|
+
perPage: 10
|
|
137
|
+
assign:
|
|
138
|
+
pullRequests: ${{ result.data.pullRequests }}
|
|
139
|
+
|
|
140
|
+
# Step 5: Fetch directory listing and workflow runs
|
|
141
|
+
- id: fetch_content_actions
|
|
142
|
+
from: issues_prs_fetched
|
|
143
|
+
to: content_actions_fetched
|
|
144
|
+
call:
|
|
145
|
+
- tool: gitHubListDirectory
|
|
146
|
+
id: dir_fetch
|
|
147
|
+
args:
|
|
148
|
+
owner: ${{ args.owner }}
|
|
149
|
+
repo: ${{ args.repo }}
|
|
150
|
+
assign:
|
|
151
|
+
directoryEntries: ${{ result.data.entries }}
|
|
152
|
+
|
|
153
|
+
- tool: gitHubListWorkflowRuns
|
|
154
|
+
id: runs_fetch
|
|
155
|
+
args:
|
|
156
|
+
owner: ${{ args.owner }}
|
|
157
|
+
repo: ${{ args.repo }}
|
|
158
|
+
perPage: 5
|
|
159
|
+
assign:
|
|
160
|
+
workflowRuns: ${{ result.data.runs }}
|
|
161
|
+
|
|
162
|
+
# Step 6: Search code in the repo
|
|
163
|
+
- id: fetch_search
|
|
164
|
+
from: content_actions_fetched
|
|
165
|
+
to: search_done
|
|
166
|
+
call:
|
|
167
|
+
- tool: gitHubSearchCode
|
|
168
|
+
id: code_search
|
|
169
|
+
args:
|
|
170
|
+
query: ${{ searchQuery() }}
|
|
171
|
+
perPage: 5
|
|
172
|
+
assign:
|
|
173
|
+
searchResults: ${{ result.data.results }}
|
|
174
|
+
|
|
175
|
+
# Display all results
|
|
176
|
+
- id: display_results
|
|
177
|
+
from: search_done
|
|
178
|
+
to: end
|
|
179
|
+
call:
|
|
180
|
+
- tool: createDocument
|
|
181
|
+
args:
|
|
182
|
+
document: markdown
|
|
183
|
+
update:
|
|
184
|
+
content:
|
|
185
|
+
markdown: |
|
|
186
|
+
## Authenticated User
|
|
187
|
+
**{{ state.user.login }}** {{#if state.user.name}}({{ state.user.name }}){{/if}} — {{ state.user.publicRepos }} public repos
|
|
188
|
+
|
|
189
|
+
{{#if state.orgs}}
|
|
190
|
+
### Organizations
|
|
191
|
+
{{#each state.orgs}}
|
|
192
|
+
- **{{ this.login }}** {{#if this.description}}— {{ this.description }}{{/if}}
|
|
193
|
+
{{/each}}
|
|
194
|
+
{{/if}}
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Repository: [{{ state.repo.fullName }}]({{ state.repo.htmlUrl }})
|
|
199
|
+
{{ state.repo.description }}
|
|
200
|
+
|
|
201
|
+
| Language | Stars | Forks | Open Issues | Default Branch |
|
|
202
|
+
|---|---|---|---|---|
|
|
203
|
+
| {{ state.repo.language }} | {{ state.repo.stars }} | {{ state.repo.forks }} | {{ state.repo.openIssues }} | {{ state.repo.defaultBranch }} |
|
|
204
|
+
|
|
205
|
+
### Branches
|
|
206
|
+
{{#each state.branches}}
|
|
207
|
+
- `{{ this.name }}` {{#if this.protected}}(protected){{/if}}
|
|
208
|
+
{{/each}}
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
### Open Issues
|
|
213
|
+
{{#each state.issues}}
|
|
214
|
+
- [#{{ this.number }}]({{ this.htmlUrl }}) {{ this.title }} — @{{ this.user }}
|
|
215
|
+
{{/each}}
|
|
216
|
+
{{#unless state.issues}}
|
|
217
|
+
No open issues.
|
|
218
|
+
{{/unless}}
|
|
219
|
+
|
|
220
|
+
### Open Pull Requests
|
|
221
|
+
{{#each state.pullRequests}}
|
|
222
|
+
- [#{{ this.number }}]({{ this.htmlUrl }}) {{ this.title }} — @{{ this.user }} {{#if this.draft}}(draft){{/if}}
|
|
223
|
+
{{/each}}
|
|
224
|
+
{{#unless state.pullRequests}}
|
|
225
|
+
No open pull requests.
|
|
226
|
+
{{/unless}}
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
### Root Directory
|
|
231
|
+
{{#each state.directoryEntries}}
|
|
232
|
+
- {{ this.type }} `{{ this.name }}`
|
|
233
|
+
{{/each}}
|
|
234
|
+
|
|
235
|
+
### Recent Workflow Runs
|
|
236
|
+
{{#each state.workflowRuns}}
|
|
237
|
+
- [{{ this.name }}]({{ this.htmlUrl }}) — {{ this.status }} {{#if this.conclusion}}({{ this.conclusion }}){{/if}}
|
|
238
|
+
{{/each}}
|
|
239
|
+
{{#unless state.workflowRuns}}
|
|
240
|
+
No workflow runs found.
|
|
241
|
+
{{/unless}}
|
|
242
|
+
|
|
243
|
+
### Code Search Results
|
|
244
|
+
{{#each state.searchResults}}
|
|
245
|
+
- `{{ this.path }}` in {{ this.repository }}
|
|
246
|
+
{{/each}}
|
|
247
|
+
{{#unless state.searchResults}}
|
|
248
|
+
No code search results.
|
|
249
|
+
{{/unless}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workflows/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./github-agent.workflow"), exports);
|
|
18
|
+
__exportStar(require("./github-repos-overview.workflow"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workflows/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0DAAwC;AACxC,mEAAiD"}
|
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@loopstack/github-oauth-example",
|
|
3
|
+
"displayName": "GitHub OAuth Example",
|
|
4
|
+
"description": "An example module demonstrating how to list GitHub repositories and issues with OAuth authentication using the Loopstack automation framework. Shows the sub-workflow pattern for handling OAuth flows.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"example",
|
|
7
|
+
"github",
|
|
8
|
+
"loopstack",
|
|
9
|
+
"oauth"
|
|
10
|
+
],
|
|
11
|
+
"version": "0.1.1",
|
|
12
|
+
"license": "Apache-2.0",
|
|
13
|
+
"author": {
|
|
14
|
+
"name": "Jakob Klippel",
|
|
15
|
+
"url": "https://github.com/loopstack-ai"
|
|
16
|
+
},
|
|
17
|
+
"main": "dist/index.js",
|
|
18
|
+
"types": "dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": "./dist/index.js",
|
|
21
|
+
"./src/*": "./src/*"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "nest build",
|
|
25
|
+
"compile": "tsc --noEmit",
|
|
26
|
+
"format": "prettier --write .",
|
|
27
|
+
"lint": "eslint .",
|
|
28
|
+
"test": "jest --passWithNoTests",
|
|
29
|
+
"watch": "nest build --watch"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@loopstack/claude-module": "^0.21.1",
|
|
33
|
+
"@loopstack/common": "^0.24.0",
|
|
34
|
+
"@loopstack/core": "^0.24.0",
|
|
35
|
+
"@loopstack/create-chat-message-tool": "^0.20.7",
|
|
36
|
+
"@loopstack/github-module": "^0.1.0",
|
|
37
|
+
"@loopstack/oauth-module": "^0.1.6",
|
|
38
|
+
"@nestjs/common": "^11.1.14",
|
|
39
|
+
"zod": "^4.3.6"
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist",
|
|
43
|
+
"src"
|
|
44
|
+
],
|
|
45
|
+
"jest": {
|
|
46
|
+
"testEnvironment": "node",
|
|
47
|
+
"rootDir": "src",
|
|
48
|
+
"testRegex": ".*\\.spec\\.ts$",
|
|
49
|
+
"transform": {
|
|
50
|
+
"^.+\\.ts$": "ts-jest"
|
|
51
|
+
},
|
|
52
|
+
"testTimeout": 10000,
|
|
53
|
+
"forceExit": true,
|
|
54
|
+
"maxWorkers": 1
|
|
55
|
+
},
|
|
56
|
+
"loopstack": {
|
|
57
|
+
"installModes": [
|
|
58
|
+
"add",
|
|
59
|
+
"install"
|
|
60
|
+
],
|
|
61
|
+
"modules": [
|
|
62
|
+
{
|
|
63
|
+
"path": "src/github-example.module.ts",
|
|
64
|
+
"className": "GitHubExampleModule"
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"workflows": [
|
|
68
|
+
{
|
|
69
|
+
"path": "src/workflows/github-repos-overview.workflow.ts",
|
|
70
|
+
"className": "GitHubReposOverviewWorkflow",
|
|
71
|
+
"propertyName": "gitHubReposOverview"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"path": "src/workflows/github-agent.workflow.ts",
|
|
75
|
+
"className": "GitHubAgentWorkflow",
|
|
76
|
+
"propertyName": "gitHubAgent"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { ClaudeModule } from '@loopstack/claude-module';
|
|
3
|
+
import { LoopCoreModule } from '@loopstack/core';
|
|
4
|
+
import { CreateChatMessageToolModule } from '@loopstack/create-chat-message-tool';
|
|
5
|
+
import { GitHubModule } from '@loopstack/github-module';
|
|
6
|
+
import { AuthenticateGitHubTask } from './tools';
|
|
7
|
+
import { GitHubAgentWorkflow, GitHubReposOverviewWorkflow } from './workflows';
|
|
8
|
+
|
|
9
|
+
@Module({
|
|
10
|
+
imports: [LoopCoreModule, CreateChatMessageToolModule, ClaudeModule, GitHubModule],
|
|
11
|
+
providers: [AuthenticateGitHubTask, GitHubReposOverviewWorkflow, GitHubAgentWorkflow],
|
|
12
|
+
exports: [AuthenticateGitHubTask, GitHubReposOverviewWorkflow, GitHubAgentWorkflow],
|
|
13
|
+
})
|
|
14
|
+
export class GitHubExampleModule {}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { Injectable, Logger } from '@nestjs/common';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import {
|
|
4
|
+
InjectDocument,
|
|
5
|
+
InjectTool,
|
|
6
|
+
Input,
|
|
7
|
+
RunContext,
|
|
8
|
+
Tool,
|
|
9
|
+
ToolInterface,
|
|
10
|
+
ToolResult,
|
|
11
|
+
ToolSideEffects,
|
|
12
|
+
WorkflowInterface,
|
|
13
|
+
WorkflowMetadataInterface,
|
|
14
|
+
} from '@loopstack/common';
|
|
15
|
+
import { CreateDocument, LinkDocument, Task } from '@loopstack/core';
|
|
16
|
+
|
|
17
|
+
const AuthenticateGitHubTaskInputSchema = z
|
|
18
|
+
.object({
|
|
19
|
+
scopes: z.array(z.string()).describe('The OAuth scopes to request (e.g. repo, user, workflow, read:org)'),
|
|
20
|
+
})
|
|
21
|
+
.strict();
|
|
22
|
+
|
|
23
|
+
type AuthenticateGitHubTaskInput = z.infer<typeof AuthenticateGitHubTaskInputSchema>;
|
|
24
|
+
|
|
25
|
+
@Injectable()
|
|
26
|
+
@Tool({
|
|
27
|
+
config: {
|
|
28
|
+
description:
|
|
29
|
+
'Launches GitHub OAuth authentication. Shows the user a sign-in prompt to authorize access to GitHub. ' +
|
|
30
|
+
'Use this when a GitHub tool returns an "unauthorized" error. ' +
|
|
31
|
+
'Pass the required OAuth scopes for the GitHub APIs you need access to. ' +
|
|
32
|
+
'IMPORTANT: When using this tool, it must be the ONLY tool call in your response. Do not combine it with other tool calls.',
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
export class AuthenticateGitHubTask implements ToolInterface<AuthenticateGitHubTaskInput> {
|
|
36
|
+
private readonly logger = new Logger(AuthenticateGitHubTask.name);
|
|
37
|
+
|
|
38
|
+
@InjectTool() private task: Task;
|
|
39
|
+
@InjectTool() private createDocument: CreateDocument;
|
|
40
|
+
@InjectDocument() private linkDocument: LinkDocument;
|
|
41
|
+
|
|
42
|
+
@Input({ schema: AuthenticateGitHubTaskInputSchema })
|
|
43
|
+
args: AuthenticateGitHubTaskInput;
|
|
44
|
+
|
|
45
|
+
async execute(
|
|
46
|
+
args: AuthenticateGitHubTaskInput,
|
|
47
|
+
ctx: RunContext,
|
|
48
|
+
parent: WorkflowInterface | ToolInterface,
|
|
49
|
+
metadata: WorkflowMetadataInterface,
|
|
50
|
+
): Promise<ToolResult> {
|
|
51
|
+
const taskResult = await this.task.execute(
|
|
52
|
+
{ workflow: 'oAuth', args: { provider: 'github', scopes: args.scopes } },
|
|
53
|
+
ctx,
|
|
54
|
+
parent,
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const effects: ToolSideEffects[] = [];
|
|
58
|
+
|
|
59
|
+
const linkResult = await this.createDocument.execute(
|
|
60
|
+
{
|
|
61
|
+
document: 'linkDocument',
|
|
62
|
+
id: 'github_auth_link',
|
|
63
|
+
validate: 'skip' as const,
|
|
64
|
+
update: {
|
|
65
|
+
content: {
|
|
66
|
+
icon: 'LockKeyhole',
|
|
67
|
+
label: 'GitHub authentication required',
|
|
68
|
+
caption: 'Complete sign-in to access GitHub',
|
|
69
|
+
href: `/pipelines/${String((taskResult.data as Record<string, unknown>).pipelineId)}`,
|
|
70
|
+
embed: true,
|
|
71
|
+
expanded: true,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
ctx,
|
|
76
|
+
this,
|
|
77
|
+
metadata,
|
|
78
|
+
);
|
|
79
|
+
if (linkResult.effects) {
|
|
80
|
+
effects.push(...linkResult.effects);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
data: taskResult.data as Record<string, unknown>,
|
|
85
|
+
effects,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async complete(
|
|
90
|
+
result: Record<string, unknown>,
|
|
91
|
+
ctx: RunContext,
|
|
92
|
+
parent: WorkflowInterface | ToolInterface,
|
|
93
|
+
metadata: WorkflowMetadataInterface,
|
|
94
|
+
): Promise<ToolResult> {
|
|
95
|
+
const data = result as { pipelineId?: string };
|
|
96
|
+
|
|
97
|
+
const effects: ToolSideEffects[] = [];
|
|
98
|
+
|
|
99
|
+
const linkResult = await this.createDocument.execute(
|
|
100
|
+
{
|
|
101
|
+
document: 'linkDocument',
|
|
102
|
+
id: 'github_auth_link',
|
|
103
|
+
validate: 'skip' as const,
|
|
104
|
+
update: {
|
|
105
|
+
content: {
|
|
106
|
+
icon: 'ShieldCheck',
|
|
107
|
+
label: 'GitHub authentication completed',
|
|
108
|
+
href: `/pipelines/${data.pipelineId}`,
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
ctx,
|
|
113
|
+
this,
|
|
114
|
+
metadata,
|
|
115
|
+
);
|
|
116
|
+
if (linkResult.effects) {
|
|
117
|
+
effects.push(...linkResult.effects);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
data: 'GitHub authentication completed successfully. You can now use GitHub tools.',
|
|
122
|
+
effects,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './authenticate-github-task.tool';
|