sedd 0.1.9 → 0.1.11
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 +140 -2
- package/commands/sedd.board.md +67 -0
- package/commands/sedd.clarify.md +23 -0
- package/commands/sedd.specify.md +22 -0
- package/dist/cli/board.d.ts +9 -0
- package/dist/cli/board.d.ts.map +1 -0
- package/dist/cli/board.js +211 -0
- package/dist/cli/board.js.map +1 -0
- package/dist/cli/clarify.d.ts +5 -1
- package/dist/cli/clarify.d.ts.map +1 -1
- package/dist/cli/clarify.js +52 -8
- package/dist/cli/clarify.js.map +1 -1
- package/dist/cli/index.js +31 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/setup-github.d.ts +5 -0
- package/dist/cli/setup-github.d.ts.map +1 -0
- package/dist/cli/setup-github.js +437 -0
- package/dist/cli/setup-github.js.map +1 -0
- package/dist/cli/specify.d.ts +1 -0
- package/dist/cli/specify.d.ts.map +1 -1
- package/dist/cli/specify.js +82 -9
- package/dist/cli/specify.js.map +1 -1
- package/dist/cli/status.d.ts.map +1 -1
- package/dist/cli/status.js +31 -0
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/tasks.d.ts.map +1 -1
- package/dist/cli/tasks.js +102 -1
- package/dist/cli/tasks.js.map +1 -1
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +21 -0
- package/dist/cli/update.js.map +1 -1
- package/dist/core/board-manager.d.ts +65 -0
- package/dist/core/board-manager.d.ts.map +1 -0
- package/dist/core/board-manager.js +326 -0
- package/dist/core/board-manager.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +117 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +11 -0
- package/dist/types/index.js.map +1 -1
- package/dist/utils/github.d.ts +105 -0
- package/dist/utils/github.d.ts.map +1 -0
- package/dist/utils/github.js +494 -0
- package/dist/utils/github.js.map +1 -0
- package/package.json +61 -61
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { GitHubIssueInfo, GitHubOrganization, GitHubProjectInfo, GitHubFieldInfo, GitHubProjectItem } from '../types/index.js';
|
|
2
|
+
export declare class GitHubOperations {
|
|
3
|
+
private cwd;
|
|
4
|
+
constructor(cwd?: string);
|
|
5
|
+
private exec;
|
|
6
|
+
private execJson;
|
|
7
|
+
/**
|
|
8
|
+
* Execute a GraphQL query using execFileSync to avoid shell quoting issues on Windows.
|
|
9
|
+
* Values must be inlined in the query string (no $variables).
|
|
10
|
+
*/
|
|
11
|
+
private execGraphQL;
|
|
12
|
+
/**
|
|
13
|
+
* Check if gh CLI is installed
|
|
14
|
+
*/
|
|
15
|
+
hasGh(): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Get gh CLI version string
|
|
18
|
+
*/
|
|
19
|
+
getGhVersion(): string | null;
|
|
20
|
+
/**
|
|
21
|
+
* Check if user is authenticated
|
|
22
|
+
*/
|
|
23
|
+
isAuthenticated(): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Get authenticated username
|
|
26
|
+
*/
|
|
27
|
+
getUsername(): string | null;
|
|
28
|
+
/**
|
|
29
|
+
* Check if the 'project' scope is available
|
|
30
|
+
*/
|
|
31
|
+
hasProjectScope(): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* List organizations the authenticated user belongs to
|
|
34
|
+
*/
|
|
35
|
+
listUserOrganizations(): GitHubOrganization[];
|
|
36
|
+
/**
|
|
37
|
+
* Detect owner/repo from git remote
|
|
38
|
+
*/
|
|
39
|
+
detectOwnerRepo(): {
|
|
40
|
+
owner: string;
|
|
41
|
+
repo: string;
|
|
42
|
+
} | null;
|
|
43
|
+
private escapeGql;
|
|
44
|
+
/**
|
|
45
|
+
* List projects for an owner (user or org)
|
|
46
|
+
*/
|
|
47
|
+
listProjects(owner: string): GitHubProjectInfo[];
|
|
48
|
+
private listOrgProjects;
|
|
49
|
+
/**
|
|
50
|
+
* Get fields for a project (including Status with options)
|
|
51
|
+
*/
|
|
52
|
+
getProjectFields(projectId: string): GitHubFieldInfo[];
|
|
53
|
+
/**
|
|
54
|
+
* Get the Status field (single select with column options)
|
|
55
|
+
*/
|
|
56
|
+
getStatusField(projectId: string): GitHubFieldInfo | null;
|
|
57
|
+
/**
|
|
58
|
+
* List items in a project (issues on the board)
|
|
59
|
+
*/
|
|
60
|
+
listProjectItems(owner: string, projectNumber: number): GitHubProjectItem[];
|
|
61
|
+
private listOrgProjectItems;
|
|
62
|
+
/**
|
|
63
|
+
* Create a GitHub issue
|
|
64
|
+
*/
|
|
65
|
+
createIssue(title: string, body: string, labels?: string[]): GitHubIssueInfo | null;
|
|
66
|
+
/**
|
|
67
|
+
* Add an issue to a project, returns the item ID
|
|
68
|
+
*/
|
|
69
|
+
addIssueToProject(projectId: string, issueUrl: string): string | null;
|
|
70
|
+
private getIssueNodeId;
|
|
71
|
+
/**
|
|
72
|
+
* Move an item to a specific column in the project
|
|
73
|
+
*/
|
|
74
|
+
moveItem(projectId: string, itemId: string, statusFieldId: string, optionId: string): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Get issue by number
|
|
77
|
+
*/
|
|
78
|
+
getIssue(number: number): GitHubIssueInfo | null;
|
|
79
|
+
/**
|
|
80
|
+
* Get issue from full URL
|
|
81
|
+
*/
|
|
82
|
+
getIssueFromUrl(url: string): GitHubIssueInfo | null;
|
|
83
|
+
/**
|
|
84
|
+
* Close an issue
|
|
85
|
+
*/
|
|
86
|
+
closeIssue(number: number): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Add a comment to an issue
|
|
89
|
+
*/
|
|
90
|
+
addIssueComment(number: number, comment: string): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Parse issue URL into components
|
|
93
|
+
*/
|
|
94
|
+
parseIssueUrl(url: string): {
|
|
95
|
+
owner: string;
|
|
96
|
+
repo: string;
|
|
97
|
+
number: number;
|
|
98
|
+
} | null;
|
|
99
|
+
/**
|
|
100
|
+
* Download images referenced in issue body to local assets/ directory.
|
|
101
|
+
* Rewrites markdown image links to relative paths.
|
|
102
|
+
*/
|
|
103
|
+
downloadIssueImages(body: string, targetDir: string): string;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/utils/github.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EAClB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,GAAG,CAAS;gBAER,GAAG,GAAE,MAAsB;IAIvC,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,QAAQ;IAShB;;;OAGG;IACH,OAAO,CAAC,WAAW;IASnB;;OAEG;IACH,KAAK,IAAI,OAAO;IAShB;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAU7B;;OAEG;IACH,eAAe,IAAI,OAAO;IAS1B;;OAEG;IACH,WAAW,IAAI,MAAM,GAAG,IAAI;IAS5B;;OAEG;IACH,eAAe,IAAI,OAAO;IAS1B;;OAEG;IACH,qBAAqB,IAAI,kBAAkB,EAAE;IAW7C;;OAEG;IACH,eAAe,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAUzD,OAAO,CAAC,SAAS;IAIjB;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAwBhD,OAAO,CAAC,eAAe;IAsBvB;;OAEG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,EAAE;IA+BtD;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAKzD;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAsC3E,OAAO,CAAC,mBAAmB;IA2B3B;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,eAAe,GAAG,IAAI;IAsBnF;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAiBrE,OAAO,CAAC,cAAc;IAetB;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAmB7F;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAmBhD;;OAEG;IACH,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAsBpD;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IASnC;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IAWzD;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAMlF;;;OAGG;IACH,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;CAuD7D"}
|
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
import { execSync, execFileSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
3
|
+
import { join, extname } from 'node:path';
|
|
4
|
+
export class GitHubOperations {
|
|
5
|
+
cwd;
|
|
6
|
+
constructor(cwd = process.cwd()) {
|
|
7
|
+
this.cwd = cwd;
|
|
8
|
+
}
|
|
9
|
+
exec(cmd) {
|
|
10
|
+
return execSync(cmd, { cwd: this.cwd, encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
11
|
+
}
|
|
12
|
+
execJson(cmd) {
|
|
13
|
+
try {
|
|
14
|
+
const output = this.exec(cmd);
|
|
15
|
+
return JSON.parse(output);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Execute a GraphQL query using execFileSync to avoid shell quoting issues on Windows.
|
|
23
|
+
* Values must be inlined in the query string (no $variables).
|
|
24
|
+
*/
|
|
25
|
+
execGraphQL(query) {
|
|
26
|
+
const result = execFileSync('gh', ['api', 'graphql', '-f', `query=${query.replace(/\n/g, ' ')}`], {
|
|
27
|
+
cwd: this.cwd,
|
|
28
|
+
encoding: 'utf-8',
|
|
29
|
+
stdio: 'pipe',
|
|
30
|
+
});
|
|
31
|
+
return JSON.parse(result.trim());
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Check if gh CLI is installed
|
|
35
|
+
*/
|
|
36
|
+
hasGh() {
|
|
37
|
+
try {
|
|
38
|
+
this.exec('gh --version');
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get gh CLI version string
|
|
47
|
+
*/
|
|
48
|
+
getGhVersion() {
|
|
49
|
+
try {
|
|
50
|
+
const output = this.exec('gh --version');
|
|
51
|
+
const match = output.match(/gh version ([\d.]+)/);
|
|
52
|
+
return match ? match[1] : null;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Check if user is authenticated
|
|
60
|
+
*/
|
|
61
|
+
isAuthenticated() {
|
|
62
|
+
try {
|
|
63
|
+
this.exec('gh auth status');
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get authenticated username
|
|
72
|
+
*/
|
|
73
|
+
getUsername() {
|
|
74
|
+
try {
|
|
75
|
+
const output = this.exec('gh api user --jq .login');
|
|
76
|
+
return output || null;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Check if the 'project' scope is available
|
|
84
|
+
*/
|
|
85
|
+
hasProjectScope() {
|
|
86
|
+
try {
|
|
87
|
+
const output = this.exec('gh auth status');
|
|
88
|
+
return output.includes('project') || output.includes('read:project');
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* List organizations the authenticated user belongs to
|
|
96
|
+
*/
|
|
97
|
+
listUserOrganizations() {
|
|
98
|
+
try {
|
|
99
|
+
const query = `query { viewer { login organizations(first: 50) { nodes { login name } } } }`;
|
|
100
|
+
const data = this.execGraphQL(query);
|
|
101
|
+
const nodes = data?.data?.viewer?.organizations?.nodes || [];
|
|
102
|
+
return nodes.map((o) => ({ login: o.login, name: o.name || o.login }));
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Detect owner/repo from git remote
|
|
110
|
+
*/
|
|
111
|
+
detectOwnerRepo() {
|
|
112
|
+
try {
|
|
113
|
+
const remote = this.exec('gh repo view --json owner,name');
|
|
114
|
+
const parsed = JSON.parse(remote);
|
|
115
|
+
return { owner: parsed.owner.login, repo: parsed.name };
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
escapeGql(val) {
|
|
122
|
+
return val.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* List projects for an owner (user or org)
|
|
126
|
+
*/
|
|
127
|
+
listProjects(owner) {
|
|
128
|
+
try {
|
|
129
|
+
const query = `query {
|
|
130
|
+
user(login: "${this.escapeGql(owner)}") {
|
|
131
|
+
projectsV2(first: 20) {
|
|
132
|
+
nodes { id number title }
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}`;
|
|
136
|
+
const data = this.execGraphQL(query);
|
|
137
|
+
const nodes = data?.data?.user?.projectsV2?.nodes;
|
|
138
|
+
if (!nodes) {
|
|
139
|
+
return this.listOrgProjects(owner);
|
|
140
|
+
}
|
|
141
|
+
return nodes.map((n) => ({
|
|
142
|
+
number: n.number,
|
|
143
|
+
id: n.id,
|
|
144
|
+
title: n.title,
|
|
145
|
+
}));
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return this.listOrgProjects(owner);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
listOrgProjects(owner) {
|
|
152
|
+
try {
|
|
153
|
+
const query = `query {
|
|
154
|
+
organization(login: "${this.escapeGql(owner)}") {
|
|
155
|
+
projectsV2(first: 20) {
|
|
156
|
+
nodes { id number title }
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}`;
|
|
160
|
+
const data = this.execGraphQL(query);
|
|
161
|
+
const nodes = data?.data?.organization?.projectsV2?.nodes;
|
|
162
|
+
if (!nodes)
|
|
163
|
+
return [];
|
|
164
|
+
return nodes.map((n) => ({
|
|
165
|
+
number: n.number,
|
|
166
|
+
id: n.id,
|
|
167
|
+
title: n.title,
|
|
168
|
+
}));
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return [];
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Get fields for a project (including Status with options)
|
|
176
|
+
*/
|
|
177
|
+
getProjectFields(projectId) {
|
|
178
|
+
try {
|
|
179
|
+
const query = `query {
|
|
180
|
+
node(id: "${this.escapeGql(projectId)}") {
|
|
181
|
+
... on ProjectV2 {
|
|
182
|
+
fields(first: 50) {
|
|
183
|
+
nodes {
|
|
184
|
+
... on ProjectV2Field { id name }
|
|
185
|
+
... on ProjectV2SingleSelectField {
|
|
186
|
+
id name
|
|
187
|
+
options { id name }
|
|
188
|
+
}
|
|
189
|
+
... on ProjectV2IterationField { id name }
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}`;
|
|
195
|
+
const data = this.execGraphQL(query);
|
|
196
|
+
const nodes = data?.data?.node?.fields?.nodes;
|
|
197
|
+
if (!nodes)
|
|
198
|
+
return [];
|
|
199
|
+
return nodes.map((n) => ({
|
|
200
|
+
id: n.id,
|
|
201
|
+
name: n.name,
|
|
202
|
+
options: n.options,
|
|
203
|
+
}));
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
return [];
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Get the Status field (single select with column options)
|
|
211
|
+
*/
|
|
212
|
+
getStatusField(projectId) {
|
|
213
|
+
const fields = this.getProjectFields(projectId);
|
|
214
|
+
return fields.find(f => f.name === 'Status' && f.options) || null;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* List items in a project (issues on the board)
|
|
218
|
+
*/
|
|
219
|
+
listProjectItems(owner, projectNumber) {
|
|
220
|
+
try {
|
|
221
|
+
const query = `query {
|
|
222
|
+
user(login: "${this.escapeGql(owner)}") {
|
|
223
|
+
projectV2(number: ${projectNumber}) {
|
|
224
|
+
items(first: 100) {
|
|
225
|
+
nodes {
|
|
226
|
+
id
|
|
227
|
+
fieldValueByName(name: "Status") {
|
|
228
|
+
... on ProjectV2ItemFieldSingleSelectValue { name }
|
|
229
|
+
}
|
|
230
|
+
content {
|
|
231
|
+
... on Issue { number title url }
|
|
232
|
+
... on DraftIssue { title }
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}`;
|
|
239
|
+
const data = this.execGraphQL(query);
|
|
240
|
+
let nodes = data?.data?.user?.projectV2?.items?.nodes;
|
|
241
|
+
if (!nodes) {
|
|
242
|
+
nodes = this.listOrgProjectItems(owner, projectNumber);
|
|
243
|
+
}
|
|
244
|
+
if (!nodes)
|
|
245
|
+
return [];
|
|
246
|
+
return nodes.map((n) => ({
|
|
247
|
+
id: n.id,
|
|
248
|
+
title: n.content?.title || '',
|
|
249
|
+
status: n.fieldValueByName?.name || '',
|
|
250
|
+
issueNumber: n.content?.number,
|
|
251
|
+
issueUrl: n.content?.url,
|
|
252
|
+
}));
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
return [];
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
listOrgProjectItems(owner, projectNumber) {
|
|
259
|
+
try {
|
|
260
|
+
const query = `query {
|
|
261
|
+
organization(login: "${this.escapeGql(owner)}") {
|
|
262
|
+
projectV2(number: ${projectNumber}) {
|
|
263
|
+
items(first: 100) {
|
|
264
|
+
nodes {
|
|
265
|
+
id
|
|
266
|
+
fieldValueByName(name: "Status") {
|
|
267
|
+
... on ProjectV2ItemFieldSingleSelectValue { name }
|
|
268
|
+
}
|
|
269
|
+
content {
|
|
270
|
+
... on Issue { number title url }
|
|
271
|
+
... on DraftIssue { title }
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}`;
|
|
278
|
+
const data = this.execGraphQL(query);
|
|
279
|
+
return data?.data?.organization?.projectV2?.items?.nodes || null;
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Create a GitHub issue
|
|
287
|
+
*/
|
|
288
|
+
createIssue(title, body, labels) {
|
|
289
|
+
try {
|
|
290
|
+
const labelArgs = labels && labels.length > 0
|
|
291
|
+
? labels.map(l => `-l "${l}"`).join(' ')
|
|
292
|
+
: '';
|
|
293
|
+
const output = this.exec(`gh issue create --title "${title.replace(/"/g, '\\"')}" --body "${body.replace(/"/g, '\\"').replace(/\n/g, '\\n')}" ${labelArgs} --json number,url,title,body,state,labels`);
|
|
294
|
+
const parsed = JSON.parse(output);
|
|
295
|
+
return {
|
|
296
|
+
number: parsed.number,
|
|
297
|
+
url: parsed.url,
|
|
298
|
+
title: parsed.title,
|
|
299
|
+
body: parsed.body || '',
|
|
300
|
+
state: parsed.state || 'OPEN',
|
|
301
|
+
labels: (parsed.labels || []).map((l) => l.name || l),
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
catch {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Add an issue to a project, returns the item ID
|
|
310
|
+
*/
|
|
311
|
+
addIssueToProject(projectId, issueUrl) {
|
|
312
|
+
try {
|
|
313
|
+
const issueNodeId = this.getIssueNodeId(issueUrl);
|
|
314
|
+
if (!issueNodeId)
|
|
315
|
+
return null;
|
|
316
|
+
const query = `mutation {
|
|
317
|
+
addProjectV2ItemById(input: { projectId: "${this.escapeGql(projectId)}", contentId: "${this.escapeGql(issueNodeId)}" }) {
|
|
318
|
+
item { id }
|
|
319
|
+
}
|
|
320
|
+
}`;
|
|
321
|
+
const data = this.execGraphQL(query);
|
|
322
|
+
return data?.data?.addProjectV2ItemById?.item?.id || null;
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
getIssueNodeId(issueUrl) {
|
|
329
|
+
try {
|
|
330
|
+
// Parse URL: https://github.com/owner/repo/issues/42
|
|
331
|
+
const match = issueUrl.match(/github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/);
|
|
332
|
+
if (!match)
|
|
333
|
+
return null;
|
|
334
|
+
const [, owner, repo, number] = match;
|
|
335
|
+
const output = this.exec(`gh api repos/${owner}/${repo}/issues/${number} --jq .node_id`);
|
|
336
|
+
return output || null;
|
|
337
|
+
}
|
|
338
|
+
catch {
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Move an item to a specific column in the project
|
|
344
|
+
*/
|
|
345
|
+
moveItem(projectId, itemId, statusFieldId, optionId) {
|
|
346
|
+
try {
|
|
347
|
+
const query = `mutation {
|
|
348
|
+
updateProjectV2ItemFieldValue(input: {
|
|
349
|
+
projectId: "${this.escapeGql(projectId)}"
|
|
350
|
+
itemId: "${this.escapeGql(itemId)}"
|
|
351
|
+
fieldId: "${this.escapeGql(statusFieldId)}"
|
|
352
|
+
value: { singleSelectOptionId: "${this.escapeGql(optionId)}" }
|
|
353
|
+
}) {
|
|
354
|
+
projectV2Item { id }
|
|
355
|
+
}
|
|
356
|
+
}`;
|
|
357
|
+
this.execGraphQL(query);
|
|
358
|
+
return true;
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Get issue by number
|
|
366
|
+
*/
|
|
367
|
+
getIssue(number) {
|
|
368
|
+
try {
|
|
369
|
+
const output = this.exec(`gh issue view ${number} --json number,url,title,body,state,labels`);
|
|
370
|
+
const parsed = JSON.parse(output);
|
|
371
|
+
return {
|
|
372
|
+
number: parsed.number,
|
|
373
|
+
url: parsed.url,
|
|
374
|
+
title: parsed.title,
|
|
375
|
+
body: parsed.body || '',
|
|
376
|
+
state: parsed.state || 'OPEN',
|
|
377
|
+
labels: (parsed.labels || []).map((l) => l.name || l),
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
catch {
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Get issue from full URL
|
|
386
|
+
*/
|
|
387
|
+
getIssueFromUrl(url) {
|
|
388
|
+
const match = url.match(/github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/);
|
|
389
|
+
if (!match)
|
|
390
|
+
return null;
|
|
391
|
+
const [, owner, repo, number] = match;
|
|
392
|
+
try {
|
|
393
|
+
const output = this.exec(`gh issue view ${number} --repo ${owner}/${repo} --json number,url,title,body,state,labels`);
|
|
394
|
+
const parsed = JSON.parse(output);
|
|
395
|
+
return {
|
|
396
|
+
number: parsed.number,
|
|
397
|
+
url: parsed.url || url,
|
|
398
|
+
title: parsed.title,
|
|
399
|
+
body: parsed.body || '',
|
|
400
|
+
state: parsed.state || 'OPEN',
|
|
401
|
+
labels: (parsed.labels || []).map((l) => l.name || l),
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
catch {
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Close an issue
|
|
410
|
+
*/
|
|
411
|
+
closeIssue(number) {
|
|
412
|
+
try {
|
|
413
|
+
this.exec(`gh issue close ${number}`);
|
|
414
|
+
return true;
|
|
415
|
+
}
|
|
416
|
+
catch {
|
|
417
|
+
return false;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Add a comment to an issue
|
|
422
|
+
*/
|
|
423
|
+
addIssueComment(number, comment) {
|
|
424
|
+
try {
|
|
425
|
+
this.exec(`gh issue comment ${number} --body "${comment.replace(/"/g, '\\"').replace(/\n/g, '\\n')}"`);
|
|
426
|
+
return true;
|
|
427
|
+
}
|
|
428
|
+
catch {
|
|
429
|
+
return false;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Parse issue URL into components
|
|
434
|
+
*/
|
|
435
|
+
parseIssueUrl(url) {
|
|
436
|
+
const match = url.match(/github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/);
|
|
437
|
+
if (!match)
|
|
438
|
+
return null;
|
|
439
|
+
return { owner: match[1], repo: match[2], number: parseInt(match[3]) };
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Download images referenced in issue body to local assets/ directory.
|
|
443
|
+
* Rewrites markdown image links to relative paths.
|
|
444
|
+
*/
|
|
445
|
+
downloadIssueImages(body, targetDir) {
|
|
446
|
+
const imageRegex = /!\[([^\]]*)\]\((https?:\/\/[^)]+)\)/g;
|
|
447
|
+
const imageExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg'];
|
|
448
|
+
const githubAttachments = 'github.com/user-attachments';
|
|
449
|
+
const matches = [];
|
|
450
|
+
let m;
|
|
451
|
+
while ((m = imageRegex.exec(body)) !== null) {
|
|
452
|
+
const url = m[2];
|
|
453
|
+
const ext = extname(new URL(url).pathname).toLowerCase();
|
|
454
|
+
if (imageExtensions.includes(ext) || url.includes(githubAttachments)) {
|
|
455
|
+
matches.push({ full: m[0], alt: m[1], url });
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
if (matches.length === 0)
|
|
459
|
+
return body;
|
|
460
|
+
const assetsDir = join(targetDir, 'assets');
|
|
461
|
+
if (!existsSync(assetsDir)) {
|
|
462
|
+
mkdirSync(assetsDir, { recursive: true });
|
|
463
|
+
}
|
|
464
|
+
let downloaded = 0;
|
|
465
|
+
let result = body;
|
|
466
|
+
for (let i = 0; i < matches.length; i++) {
|
|
467
|
+
const { full, alt, url } = matches[i];
|
|
468
|
+
const urlExt = extname(new URL(url).pathname).toLowerCase();
|
|
469
|
+
const ext = imageExtensions.includes(urlExt) ? urlExt : '.png';
|
|
470
|
+
const filename = `image-${String(i + 1).padStart(3, '0')}${ext}`;
|
|
471
|
+
const filepath = join(assetsDir, filename);
|
|
472
|
+
try {
|
|
473
|
+
execSync(`curl -sL "${url}" -o "${filepath}"`, {
|
|
474
|
+
cwd: this.cwd,
|
|
475
|
+
encoding: 'utf-8',
|
|
476
|
+
stdio: 'pipe',
|
|
477
|
+
timeout: 30000,
|
|
478
|
+
});
|
|
479
|
+
if (existsSync(filepath)) {
|
|
480
|
+
result = result.replace(full, ``);
|
|
481
|
+
downloaded++;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
catch {
|
|
485
|
+
// Keep original link on failure
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
if (downloaded > 0) {
|
|
489
|
+
console.log(` ✓ Downloaded ${downloaded} image${downloaded > 1 ? 's' : ''} to assets/`);
|
|
490
|
+
}
|
|
491
|
+
return result;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/utils/github.ts"],"names":[],"mappings":"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"}
|