@sudocode-ai/integration-github 0.1.14
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/gh-client.d.ts +153 -0
- package/dist/gh-client.d.ts.map +1 -0
- package/dist/gh-client.js +165 -0
- package/dist/gh-client.js.map +1 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +297 -0
- package/dist/index.js.map +1 -0
- package/dist/mappers.d.ts +88 -0
- package/dist/mappers.d.ts.map +1 -0
- package/dist/mappers.js +201 -0
- package/dist/mappers.js.map +1 -0
- package/dist/url-parser.d.ts +90 -0
- package/dist/url-parser.d.ts.map +1 -0
- package/dist/url-parser.js +145 -0
- package/dist/url-parser.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub CLI (gh) wrapper for API calls
|
|
3
|
+
*
|
|
4
|
+
* Uses the `gh` CLI for authentication and API requests.
|
|
5
|
+
* This avoids managing tokens directly - users authenticate via `gh auth login`.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Error thrown when gh CLI is not authenticated
|
|
9
|
+
*/
|
|
10
|
+
export declare class GhAuthError extends Error {
|
|
11
|
+
constructor(message?: string);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Error thrown when a GitHub resource is not found
|
|
15
|
+
*/
|
|
16
|
+
export declare class GhNotFoundError extends Error {
|
|
17
|
+
constructor(resource: string);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Error thrown when rate limited by GitHub API
|
|
21
|
+
*/
|
|
22
|
+
export declare class GhRateLimitError extends Error {
|
|
23
|
+
constructor(retryAfter?: number);
|
|
24
|
+
retryAfter?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Error thrown when gh CLI is not installed
|
|
28
|
+
*/
|
|
29
|
+
export declare class GhNotInstalledError extends Error {
|
|
30
|
+
constructor();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Options for gh API calls
|
|
34
|
+
*/
|
|
35
|
+
export interface GhApiOptions {
|
|
36
|
+
/** HTTP method (default: GET) */
|
|
37
|
+
method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
38
|
+
/** Request body for POST/PUT/PATCH */
|
|
39
|
+
body?: Record<string, unknown>;
|
|
40
|
+
/** Additional headers */
|
|
41
|
+
headers?: Record<string, string>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Execute a gh api command and parse JSON response
|
|
45
|
+
*
|
|
46
|
+
* @param endpoint - API endpoint (e.g., "/repos/owner/repo/issues/123")
|
|
47
|
+
* @param options - Optional API options
|
|
48
|
+
* @returns Parsed JSON response
|
|
49
|
+
*/
|
|
50
|
+
export declare function ghApi<T>(endpoint: string, options?: GhApiOptions): Promise<T>;
|
|
51
|
+
/**
|
|
52
|
+
* Check if gh CLI is authenticated
|
|
53
|
+
*
|
|
54
|
+
* @returns true if authenticated, false otherwise
|
|
55
|
+
*/
|
|
56
|
+
export declare function ghAuthStatus(): Promise<boolean>;
|
|
57
|
+
/**
|
|
58
|
+
* Check if gh CLI is installed and available
|
|
59
|
+
*
|
|
60
|
+
* @returns true if gh CLI is available
|
|
61
|
+
*/
|
|
62
|
+
export declare function isGhInstalled(): Promise<boolean>;
|
|
63
|
+
/**
|
|
64
|
+
* Get the authenticated user's login
|
|
65
|
+
*
|
|
66
|
+
* @returns GitHub username or null if not authenticated
|
|
67
|
+
*/
|
|
68
|
+
export declare function getAuthenticatedUser(): Promise<string | null>;
|
|
69
|
+
/**
|
|
70
|
+
* GitHub user/author from API
|
|
71
|
+
*/
|
|
72
|
+
export interface GitHubUser {
|
|
73
|
+
login: string;
|
|
74
|
+
id: number;
|
|
75
|
+
avatar_url: string;
|
|
76
|
+
html_url: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* GitHub label from API
|
|
80
|
+
*/
|
|
81
|
+
export interface GitHubLabel {
|
|
82
|
+
id: number;
|
|
83
|
+
name: string;
|
|
84
|
+
color: string;
|
|
85
|
+
description?: string;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* GitHub issue from API
|
|
89
|
+
*/
|
|
90
|
+
export interface GitHubIssue {
|
|
91
|
+
id: number;
|
|
92
|
+
number: number;
|
|
93
|
+
title: string;
|
|
94
|
+
body: string | null;
|
|
95
|
+
state: "open" | "closed";
|
|
96
|
+
state_reason?: "completed" | "not_planned" | "reopened" | null;
|
|
97
|
+
html_url: string;
|
|
98
|
+
user: GitHubUser | null;
|
|
99
|
+
labels: GitHubLabel[];
|
|
100
|
+
comments: number;
|
|
101
|
+
created_at: string;
|
|
102
|
+
updated_at: string;
|
|
103
|
+
closed_at: string | null;
|
|
104
|
+
/** Present only on pull requests - used to filter them out */
|
|
105
|
+
pull_request?: {
|
|
106
|
+
url: string;
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* GitHub issue comment from API
|
|
111
|
+
*/
|
|
112
|
+
export interface GitHubComment {
|
|
113
|
+
id: number;
|
|
114
|
+
body: string;
|
|
115
|
+
user: GitHubUser | null;
|
|
116
|
+
html_url: string;
|
|
117
|
+
created_at: string;
|
|
118
|
+
updated_at: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* GitHub discussion from API (GraphQL structure)
|
|
122
|
+
*/
|
|
123
|
+
export interface GitHubDiscussion {
|
|
124
|
+
id: string;
|
|
125
|
+
number: number;
|
|
126
|
+
title: string;
|
|
127
|
+
body: string;
|
|
128
|
+
url: string;
|
|
129
|
+
author: {
|
|
130
|
+
login: string;
|
|
131
|
+
} | null;
|
|
132
|
+
category: {
|
|
133
|
+
name: string;
|
|
134
|
+
};
|
|
135
|
+
comments: {
|
|
136
|
+
totalCount: number;
|
|
137
|
+
};
|
|
138
|
+
createdAt: string;
|
|
139
|
+
updatedAt: string;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* GitHub discussion comment from GraphQL
|
|
143
|
+
*/
|
|
144
|
+
export interface GitHubDiscussionComment {
|
|
145
|
+
id: string;
|
|
146
|
+
body: string;
|
|
147
|
+
author: {
|
|
148
|
+
login: string;
|
|
149
|
+
} | null;
|
|
150
|
+
url: string;
|
|
151
|
+
createdAt: string;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=gh-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gh-client.d.ts","sourceRoot":"","sources":["../src/gh-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH;;GAEG;AACH,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,GAAE,MAA2D;CAIjF;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,QAAQ,EAAE,MAAM;CAI7B;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,UAAU,CAAC,EAAE,MAAM;IAS/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;;CAK7C;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrD,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,yBAAyB;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAmDD;;;;;;GAMG;AACH,wBAAsB,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAyBnF;AAED;;;;GAIG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAUrD;AAED;;;;GAIG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAOtD;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQnE;AAMD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;IACzB,YAAY,CAAC,EAAE,WAAW,GAAG,aAAa,GAAG,UAAU,GAAG,IAAI,CAAC;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,8DAA8D;IAC9D,YAAY,CAAC,EAAE;QACb,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,IAAI,CAAC;IACT,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,QAAQ,EAAE;QACR,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,IAAI,CAAC;IACT,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub CLI (gh) wrapper for API calls
|
|
3
|
+
*
|
|
4
|
+
* Uses the `gh` CLI for authentication and API requests.
|
|
5
|
+
* This avoids managing tokens directly - users authenticate via `gh auth login`.
|
|
6
|
+
*/
|
|
7
|
+
import { exec } from "child_process";
|
|
8
|
+
import { promisify } from "util";
|
|
9
|
+
const execAsync = promisify(exec);
|
|
10
|
+
/**
|
|
11
|
+
* Error thrown when gh CLI is not authenticated
|
|
12
|
+
*/
|
|
13
|
+
export class GhAuthError extends Error {
|
|
14
|
+
constructor(message = "GitHub CLI not authenticated. Run: gh auth login") {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = "GhAuthError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Error thrown when a GitHub resource is not found
|
|
21
|
+
*/
|
|
22
|
+
export class GhNotFoundError extends Error {
|
|
23
|
+
constructor(resource) {
|
|
24
|
+
super(`GitHub resource not found: ${resource}`);
|
|
25
|
+
this.name = "GhNotFoundError";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Error thrown when rate limited by GitHub API
|
|
30
|
+
*/
|
|
31
|
+
export class GhRateLimitError extends Error {
|
|
32
|
+
constructor(retryAfter) {
|
|
33
|
+
super(retryAfter
|
|
34
|
+
? `GitHub API rate limit exceeded. Retry after ${retryAfter} seconds.`
|
|
35
|
+
: "GitHub API rate limit exceeded.");
|
|
36
|
+
this.name = "GhRateLimitError";
|
|
37
|
+
this.retryAfter = retryAfter;
|
|
38
|
+
}
|
|
39
|
+
retryAfter;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Error thrown when gh CLI is not installed
|
|
43
|
+
*/
|
|
44
|
+
export class GhNotInstalledError extends Error {
|
|
45
|
+
constructor() {
|
|
46
|
+
super("GitHub CLI (gh) is not installed. Install from: https://cli.github.com/");
|
|
47
|
+
this.name = "GhNotInstalledError";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Execute a gh CLI command and return the output
|
|
52
|
+
*
|
|
53
|
+
* @param args - Arguments to pass to gh
|
|
54
|
+
* @returns Command output
|
|
55
|
+
* @throws GhNotInstalledError if gh is not installed
|
|
56
|
+
* @throws GhAuthError if not authenticated
|
|
57
|
+
*/
|
|
58
|
+
async function execGh(args) {
|
|
59
|
+
const command = `gh ${args.join(" ")}`;
|
|
60
|
+
try {
|
|
61
|
+
const { stdout } = await execAsync(command, {
|
|
62
|
+
maxBuffer: 10 * 1024 * 1024, // 10MB buffer for large responses
|
|
63
|
+
});
|
|
64
|
+
return stdout;
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
const execError = error;
|
|
68
|
+
const stderr = execError.stderr || execError.message || "";
|
|
69
|
+
// Check for common error conditions
|
|
70
|
+
if (stderr.includes("command not found") || stderr.includes("not recognized")) {
|
|
71
|
+
throw new GhNotInstalledError();
|
|
72
|
+
}
|
|
73
|
+
if (stderr.includes("not logged in") ||
|
|
74
|
+
stderr.includes("authentication") ||
|
|
75
|
+
stderr.includes("gh auth login")) {
|
|
76
|
+
throw new GhAuthError();
|
|
77
|
+
}
|
|
78
|
+
if (stderr.includes("404") || stderr.includes("Not Found")) {
|
|
79
|
+
throw new GhNotFoundError(args.join(" "));
|
|
80
|
+
}
|
|
81
|
+
if (stderr.includes("rate limit") || stderr.includes("403")) {
|
|
82
|
+
// Try to extract retry-after from error
|
|
83
|
+
const retryMatch = stderr.match(/retry after (\d+)/i);
|
|
84
|
+
const retryAfter = retryMatch ? parseInt(retryMatch[1], 10) : undefined;
|
|
85
|
+
throw new GhRateLimitError(retryAfter);
|
|
86
|
+
}
|
|
87
|
+
// Re-throw with better context
|
|
88
|
+
throw new Error(`gh command failed: ${stderr}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Execute a gh api command and parse JSON response
|
|
93
|
+
*
|
|
94
|
+
* @param endpoint - API endpoint (e.g., "/repos/owner/repo/issues/123")
|
|
95
|
+
* @param options - Optional API options
|
|
96
|
+
* @returns Parsed JSON response
|
|
97
|
+
*/
|
|
98
|
+
export async function ghApi(endpoint, options) {
|
|
99
|
+
const args = ["api"];
|
|
100
|
+
// Add method if not GET
|
|
101
|
+
if (options?.method && options.method !== "GET") {
|
|
102
|
+
args.push("-X", options.method);
|
|
103
|
+
}
|
|
104
|
+
// Add headers
|
|
105
|
+
if (options?.headers) {
|
|
106
|
+
for (const [key, value] of Object.entries(options.headers)) {
|
|
107
|
+
args.push("-H", `${key}: ${value}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Add body for POST/PUT/PATCH
|
|
111
|
+
if (options?.body) {
|
|
112
|
+
args.push("-f", JSON.stringify(options.body));
|
|
113
|
+
}
|
|
114
|
+
// Add endpoint (escape special characters)
|
|
115
|
+
args.push(`"${endpoint}"`);
|
|
116
|
+
const output = await execGh(args);
|
|
117
|
+
return JSON.parse(output);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Check if gh CLI is authenticated
|
|
121
|
+
*
|
|
122
|
+
* @returns true if authenticated, false otherwise
|
|
123
|
+
*/
|
|
124
|
+
export async function ghAuthStatus() {
|
|
125
|
+
try {
|
|
126
|
+
await execGh(["auth", "status"]);
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
if (error instanceof GhNotInstalledError) {
|
|
131
|
+
throw error; // Re-throw if not installed
|
|
132
|
+
}
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Check if gh CLI is installed and available
|
|
138
|
+
*
|
|
139
|
+
* @returns true if gh CLI is available
|
|
140
|
+
*/
|
|
141
|
+
export async function isGhInstalled() {
|
|
142
|
+
try {
|
|
143
|
+
await execGh(["--version"]);
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Get the authenticated user's login
|
|
152
|
+
*
|
|
153
|
+
* @returns GitHub username or null if not authenticated
|
|
154
|
+
*/
|
|
155
|
+
export async function getAuthenticatedUser() {
|
|
156
|
+
try {
|
|
157
|
+
const output = await execGh(["auth", "status", "-t"]);
|
|
158
|
+
const match = output.match(/Logged in to github\.com account (\S+)/);
|
|
159
|
+
return match ? match[1] : null;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=gh-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gh-client.js","sourceRoot":"","sources":["../src/gh-client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Integration Plugin for sudocode
|
|
3
|
+
*
|
|
4
|
+
* Provides on-demand import of GitHub issues and discussions into sudocode specs.
|
|
5
|
+
* Uses the `gh` CLI for authentication and API calls - no token management required.
|
|
6
|
+
*/
|
|
7
|
+
import type { IntegrationPlugin, IntegrationProvider, OnDemandImportCapable, ExternalEntity, ExternalComment, ExternalChange, SearchOptions, SearchResult, Spec, Issue } from "@sudocode-ai/types";
|
|
8
|
+
import { GITHUB_URL_PATTERNS, type GitHubEntityType } from "./url-parser.js";
|
|
9
|
+
/**
|
|
10
|
+
* GitHub-specific configuration options
|
|
11
|
+
* Currently empty since we use gh CLI for auth
|
|
12
|
+
*/
|
|
13
|
+
export interface GitHubOptions {
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* GitHub integration plugin
|
|
17
|
+
*/
|
|
18
|
+
declare const githubPlugin: IntegrationPlugin;
|
|
19
|
+
/**
|
|
20
|
+
* GitHub provider implementation
|
|
21
|
+
*
|
|
22
|
+
* Implements IntegrationProvider + OnDemandImportCapable for importing
|
|
23
|
+
* GitHub issues and discussions into sudocode specs.
|
|
24
|
+
*/
|
|
25
|
+
declare class GitHubProvider implements IntegrationProvider, OnDemandImportCapable {
|
|
26
|
+
readonly name = "github";
|
|
27
|
+
readonly supportsWatch = false;
|
|
28
|
+
readonly supportsPolling = false;
|
|
29
|
+
readonly supportsOnDemandImport = true;
|
|
30
|
+
readonly supportsSearch = true;
|
|
31
|
+
readonly supportsPush = false;
|
|
32
|
+
private initialized;
|
|
33
|
+
constructor(_options: GitHubOptions);
|
|
34
|
+
initialize(): Promise<void>;
|
|
35
|
+
validate(): Promise<{
|
|
36
|
+
valid: boolean;
|
|
37
|
+
errors: string[];
|
|
38
|
+
}>;
|
|
39
|
+
dispose(): Promise<void>;
|
|
40
|
+
canHandleUrl(url: string): boolean;
|
|
41
|
+
parseUrl(url: string): {
|
|
42
|
+
externalId: string;
|
|
43
|
+
metadata?: Record<string, unknown>;
|
|
44
|
+
} | null;
|
|
45
|
+
fetchByUrl(url: string): Promise<ExternalEntity | null>;
|
|
46
|
+
fetchEntity(externalId: string): Promise<ExternalEntity | null>;
|
|
47
|
+
fetchComments(externalId: string): Promise<ExternalComment[]>;
|
|
48
|
+
refreshEntities(externalIds: string[]): Promise<(ExternalEntity | null)[]>;
|
|
49
|
+
searchEntities(query?: string, options?: SearchOptions): Promise<ExternalEntity[] | SearchResult>;
|
|
50
|
+
createEntity(_entity: Partial<Spec | Issue>): Promise<string>;
|
|
51
|
+
updateEntity(_externalId: string, _entity: Partial<Spec | Issue>): Promise<void>;
|
|
52
|
+
deleteEntity(_externalId: string): Promise<void>;
|
|
53
|
+
getChangesSince(_timestamp: Date): Promise<ExternalChange[]>;
|
|
54
|
+
mapToSudocode(external: ExternalEntity): {
|
|
55
|
+
spec?: Partial<Spec>;
|
|
56
|
+
issue?: Partial<Issue>;
|
|
57
|
+
};
|
|
58
|
+
mapFromSudocode(_entity: Spec | Issue): Partial<ExternalEntity>;
|
|
59
|
+
}
|
|
60
|
+
export type { GitHubEntityType };
|
|
61
|
+
export { GITHUB_URL_PATTERNS };
|
|
62
|
+
export { GhAuthError, GhNotFoundError, GhNotInstalledError, GhRateLimitError } from "./gh-client.js";
|
|
63
|
+
export { canHandleUrl, parseUrl, parseGitHubUrl, parseExternalId } from "./url-parser.js";
|
|
64
|
+
export { ghApi, ghAuthStatus, isGhInstalled } from "./gh-client.js";
|
|
65
|
+
export { mapGitHubIssueToExternal, mapGitHubCommentToExternal, mapToSudocodeSpec, type ImportedSpecData, } from "./mappers.js";
|
|
66
|
+
export { GitHubProvider };
|
|
67
|
+
export default githubPlugin;
|
|
68
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Integration Plugin for sudocode
|
|
3
|
+
*
|
|
4
|
+
* Provides on-demand import of GitHub issues and discussions into sudocode specs.
|
|
5
|
+
* Uses the `gh` CLI for authentication and API calls - no token management required.
|
|
6
|
+
*/
|
|
7
|
+
// Internal utilities
|
|
8
|
+
import { canHandleUrl as canHandle, parseUrl as parse, parseGitHubUrl, parseExternalId, GITHUB_URL_PATTERNS, } from "./url-parser.js";
|
|
9
|
+
import { ghApi, ghAuthStatus, isGhInstalled, GhAuthError, GhNotFoundError, GhNotInstalledError, } from "./gh-client.js";
|
|
10
|
+
import { mapGitHubIssueToExternal, mapGitHubCommentToExternal, mapToSudocodeSpec, } from "./mappers.js";
|
|
11
|
+
/**
|
|
12
|
+
* GitHub integration plugin
|
|
13
|
+
*/
|
|
14
|
+
const githubPlugin = {
|
|
15
|
+
name: "github",
|
|
16
|
+
displayName: "GitHub Issues",
|
|
17
|
+
version: "0.1.0",
|
|
18
|
+
description: "Import GitHub issues and discussions into sudocode specs using gh CLI",
|
|
19
|
+
configSchema: {
|
|
20
|
+
type: "object",
|
|
21
|
+
properties: {},
|
|
22
|
+
// No required properties - auth handled by gh CLI
|
|
23
|
+
},
|
|
24
|
+
validateConfig(_options) {
|
|
25
|
+
// No configuration to validate - auth is via gh CLI
|
|
26
|
+
return {
|
|
27
|
+
valid: true,
|
|
28
|
+
errors: [],
|
|
29
|
+
warnings: [],
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
async testConnection(_options, _projectPath) {
|
|
33
|
+
// Check if gh CLI is installed
|
|
34
|
+
const installed = await isGhInstalled();
|
|
35
|
+
if (!installed) {
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
configured: false,
|
|
39
|
+
enabled: true,
|
|
40
|
+
error: "GitHub CLI (gh) is not installed. Install from: https://cli.github.com/",
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
// Check if authenticated
|
|
44
|
+
const authenticated = await ghAuthStatus();
|
|
45
|
+
if (!authenticated) {
|
|
46
|
+
return {
|
|
47
|
+
success: false,
|
|
48
|
+
configured: false,
|
|
49
|
+
enabled: true,
|
|
50
|
+
error: "GitHub CLI not authenticated. Run: gh auth login",
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
success: true,
|
|
55
|
+
configured: true,
|
|
56
|
+
enabled: true,
|
|
57
|
+
details: {
|
|
58
|
+
authMethod: "gh-cli",
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
createProvider(options, _projectPath) {
|
|
63
|
+
return new GitHubProvider(options);
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* GitHub provider implementation
|
|
68
|
+
*
|
|
69
|
+
* Implements IntegrationProvider + OnDemandImportCapable for importing
|
|
70
|
+
* GitHub issues and discussions into sudocode specs.
|
|
71
|
+
*/
|
|
72
|
+
class GitHubProvider {
|
|
73
|
+
name = "github";
|
|
74
|
+
// Capability flags
|
|
75
|
+
supportsWatch = false; // No real-time watching (would need webhooks)
|
|
76
|
+
supportsPolling = false; // No polling (on-demand only)
|
|
77
|
+
supportsOnDemandImport = true; // Primary capability
|
|
78
|
+
supportsSearch = true; // Can search repositories
|
|
79
|
+
supportsPush = false; // Read-only integration
|
|
80
|
+
initialized = false;
|
|
81
|
+
constructor(_options) {
|
|
82
|
+
// Options currently unused - auth handled by gh CLI
|
|
83
|
+
}
|
|
84
|
+
// ===========================================================================
|
|
85
|
+
// Lifecycle
|
|
86
|
+
// ===========================================================================
|
|
87
|
+
async initialize() {
|
|
88
|
+
// Verify gh CLI is available and authenticated
|
|
89
|
+
const installed = await isGhInstalled();
|
|
90
|
+
if (!installed) {
|
|
91
|
+
throw new GhNotInstalledError();
|
|
92
|
+
}
|
|
93
|
+
const authenticated = await ghAuthStatus();
|
|
94
|
+
if (!authenticated) {
|
|
95
|
+
throw new GhAuthError();
|
|
96
|
+
}
|
|
97
|
+
this.initialized = true;
|
|
98
|
+
console.log("[github] Provider initialized successfully");
|
|
99
|
+
}
|
|
100
|
+
async validate() {
|
|
101
|
+
const errors = [];
|
|
102
|
+
const installed = await isGhInstalled();
|
|
103
|
+
if (!installed) {
|
|
104
|
+
errors.push("GitHub CLI (gh) is not installed");
|
|
105
|
+
return { valid: false, errors };
|
|
106
|
+
}
|
|
107
|
+
const authenticated = await ghAuthStatus();
|
|
108
|
+
if (!authenticated) {
|
|
109
|
+
errors.push("GitHub CLI not authenticated. Run: gh auth login");
|
|
110
|
+
return { valid: false, errors };
|
|
111
|
+
}
|
|
112
|
+
return { valid: true, errors: [] };
|
|
113
|
+
}
|
|
114
|
+
async dispose() {
|
|
115
|
+
this.initialized = false;
|
|
116
|
+
console.log("[github] Provider disposed");
|
|
117
|
+
}
|
|
118
|
+
// ===========================================================================
|
|
119
|
+
// OnDemandImportCapable Implementation
|
|
120
|
+
// ===========================================================================
|
|
121
|
+
canHandleUrl(url) {
|
|
122
|
+
return canHandle(url);
|
|
123
|
+
}
|
|
124
|
+
parseUrl(url) {
|
|
125
|
+
return parse(url);
|
|
126
|
+
}
|
|
127
|
+
async fetchByUrl(url) {
|
|
128
|
+
const parsed = parseGitHubUrl(url);
|
|
129
|
+
if (!parsed) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
return this.fetchEntity(parsed.externalId);
|
|
133
|
+
}
|
|
134
|
+
async fetchEntity(externalId) {
|
|
135
|
+
const parsed = parseExternalId(externalId);
|
|
136
|
+
if (!parsed) {
|
|
137
|
+
console.warn(`[github] Invalid external ID format: ${externalId}`);
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
const { owner, repo, number } = parsed;
|
|
141
|
+
try {
|
|
142
|
+
// Fetch issue via gh api
|
|
143
|
+
const issue = await ghApi(`/repos/${owner}/${repo}/issues/${number}`);
|
|
144
|
+
return mapGitHubIssueToExternal(issue, owner, repo);
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
if (error instanceof GhNotFoundError) {
|
|
148
|
+
console.log(`[github] Entity not found: ${externalId}`);
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
throw error;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
async fetchComments(externalId) {
|
|
155
|
+
const parsed = parseExternalId(externalId);
|
|
156
|
+
if (!parsed) {
|
|
157
|
+
console.warn(`[github] Invalid external ID format: ${externalId}`);
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
const { owner, repo, number } = parsed;
|
|
161
|
+
try {
|
|
162
|
+
const comments = await ghApi(`/repos/${owner}/${repo}/issues/${number}/comments`);
|
|
163
|
+
return comments.map(mapGitHubCommentToExternal);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
if (error instanceof GhNotFoundError) {
|
|
167
|
+
return [];
|
|
168
|
+
}
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async refreshEntities(externalIds) {
|
|
173
|
+
// Fetch entities in sequence (to avoid rate limiting)
|
|
174
|
+
const results = [];
|
|
175
|
+
for (const id of externalIds) {
|
|
176
|
+
try {
|
|
177
|
+
const entity = await this.fetchEntity(id);
|
|
178
|
+
results.push(entity);
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
results.push(null);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return results;
|
|
185
|
+
}
|
|
186
|
+
// ===========================================================================
|
|
187
|
+
// IntegrationProvider Implementation
|
|
188
|
+
// ===========================================================================
|
|
189
|
+
async searchEntities(query, options) {
|
|
190
|
+
const page = options?.page || 1;
|
|
191
|
+
const perPage = Math.min(options?.perPage || 20, 100);
|
|
192
|
+
try {
|
|
193
|
+
// If we have a repo but no query, list issues from that repo
|
|
194
|
+
if (!query && options?.repo) {
|
|
195
|
+
const [owner, repo] = options.repo.split("/");
|
|
196
|
+
if (!owner || !repo) {
|
|
197
|
+
console.warn("[github] Invalid repo format, expected owner/repo");
|
|
198
|
+
return { results: [], pagination: { page, perPage, hasMore: false } };
|
|
199
|
+
}
|
|
200
|
+
// Use GitHub Issues API to list repo issues
|
|
201
|
+
// Note: GitHub's Issues API returns both issues and PRs, so we filter out PRs
|
|
202
|
+
const allItems = await ghApi(`/repos/${owner}/${repo}/issues?state=all&per_page=${perPage}&page=${page}&sort=updated&direction=desc`);
|
|
203
|
+
// Filter out pull requests (they have a pull_request property)
|
|
204
|
+
const issues = allItems.filter((item) => !item.pull_request);
|
|
205
|
+
const results = issues.map((issue) => mapGitHubIssueToExternal(issue, owner, repo));
|
|
206
|
+
return {
|
|
207
|
+
results,
|
|
208
|
+
pagination: {
|
|
209
|
+
page,
|
|
210
|
+
perPage,
|
|
211
|
+
// Note: hasMore may be inaccurate since we filter client-side
|
|
212
|
+
hasMore: allItems.length === perPage,
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
// If no query and no repo, return empty
|
|
217
|
+
if (!query) {
|
|
218
|
+
console.warn("[github] Search requires a query or repo");
|
|
219
|
+
return [];
|
|
220
|
+
}
|
|
221
|
+
// Use GitHub search API with pagination
|
|
222
|
+
// Add is:issue to exclude PRs from search results
|
|
223
|
+
const searchQuery = query.includes("is:issue") || query.includes("is:pr")
|
|
224
|
+
? query
|
|
225
|
+
: `${query} is:issue`;
|
|
226
|
+
const result = await ghApi(`/search/issues?q=${encodeURIComponent(searchQuery)}&per_page=${perPage}&page=${page}`);
|
|
227
|
+
// Filter out any PRs that might still come through
|
|
228
|
+
const issues = result.items.filter((item) => !item.pull_request);
|
|
229
|
+
const results = issues.map((issue) => {
|
|
230
|
+
// Extract owner/repo from html_url
|
|
231
|
+
const urlMatch = issue.html_url.match(/github\.com\/([^/]+)\/([^/]+)\/issues\/\d+/);
|
|
232
|
+
const owner = urlMatch?.[1] || "unknown";
|
|
233
|
+
const repo = urlMatch?.[2] || "unknown";
|
|
234
|
+
return mapGitHubIssueToExternal(issue, owner, repo);
|
|
235
|
+
});
|
|
236
|
+
// If options were provided, return SearchResult with pagination
|
|
237
|
+
if (options) {
|
|
238
|
+
return {
|
|
239
|
+
results,
|
|
240
|
+
pagination: {
|
|
241
|
+
page,
|
|
242
|
+
perPage,
|
|
243
|
+
hasMore: result.total_count > page * perPage,
|
|
244
|
+
totalCount: result.total_count,
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
// For backward compatibility, return just the array if no options
|
|
249
|
+
return results;
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
console.error("[github] Search failed:", error);
|
|
253
|
+
return options ? { results: [], pagination: { page, perPage, hasMore: false } } : [];
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
async createEntity(_entity) {
|
|
257
|
+
// Read-only integration - push not supported
|
|
258
|
+
throw new Error("GitHub integration is read-only. Push not supported.");
|
|
259
|
+
}
|
|
260
|
+
async updateEntity(_externalId, _entity) {
|
|
261
|
+
// Read-only integration - push not supported
|
|
262
|
+
throw new Error("GitHub integration is read-only. Push not supported.");
|
|
263
|
+
}
|
|
264
|
+
async deleteEntity(_externalId) {
|
|
265
|
+
// Read-only integration - push not supported
|
|
266
|
+
throw new Error("GitHub integration is read-only. Delete not supported.");
|
|
267
|
+
}
|
|
268
|
+
async getChangesSince(_timestamp) {
|
|
269
|
+
// No polling support - on-demand only
|
|
270
|
+
return [];
|
|
271
|
+
}
|
|
272
|
+
mapToSudocode(external) {
|
|
273
|
+
// GitHub entities always map to specs
|
|
274
|
+
// ImportedSpecData extends Partial<Spec> with optional labels field
|
|
275
|
+
const specData = mapToSudocodeSpec(external);
|
|
276
|
+
// Extract labels separately as they're stored as tags at a different layer
|
|
277
|
+
const { labels: _labels, ...spec } = specData;
|
|
278
|
+
return { spec };
|
|
279
|
+
}
|
|
280
|
+
mapFromSudocode(_entity) {
|
|
281
|
+
// Read-only integration - reverse mapping not needed
|
|
282
|
+
throw new Error("GitHub integration is read-only. Reverse mapping not supported.");
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// Export URL pattern constants for external use
|
|
286
|
+
export { GITHUB_URL_PATTERNS };
|
|
287
|
+
// Export error classes
|
|
288
|
+
export { GhAuthError, GhNotFoundError, GhNotInstalledError, GhRateLimitError } from "./gh-client.js";
|
|
289
|
+
// Export utility functions
|
|
290
|
+
export { canHandleUrl, parseUrl, parseGitHubUrl, parseExternalId } from "./url-parser.js";
|
|
291
|
+
export { ghApi, ghAuthStatus, isGhInstalled } from "./gh-client.js";
|
|
292
|
+
export { mapGitHubIssueToExternal, mapGitHubCommentToExternal, mapToSudocodeSpec, } from "./mappers.js";
|
|
293
|
+
// Export provider class for direct instantiation
|
|
294
|
+
export { GitHubProvider };
|
|
295
|
+
// Default export is the plugin
|
|
296
|
+
export default githubPlugin;
|
|
297
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entity mapping utilities for GitHub API → sudocode
|
|
3
|
+
*
|
|
4
|
+
* Converts GitHub API responses to ExternalEntity format
|
|
5
|
+
* and maps to sudocode Spec format.
|
|
6
|
+
*/
|
|
7
|
+
import type { ExternalEntity, ExternalComment, Spec } from "@sudocode-ai/types";
|
|
8
|
+
import type { GitHubIssue, GitHubComment, GitHubDiscussion, GitHubDiscussionComment } from "./gh-client.js";
|
|
9
|
+
import { type GitHubEntityType } from "./url-parser.js";
|
|
10
|
+
/**
|
|
11
|
+
* Map a GitHub issue to ExternalEntity
|
|
12
|
+
*
|
|
13
|
+
* @param issue - GitHub issue from API
|
|
14
|
+
* @param owner - Repository owner
|
|
15
|
+
* @param repo - Repository name
|
|
16
|
+
* @returns ExternalEntity
|
|
17
|
+
*/
|
|
18
|
+
export declare function mapGitHubIssueToExternal(issue: GitHubIssue, owner: string, repo: string): ExternalEntity;
|
|
19
|
+
/**
|
|
20
|
+
* Map a GitHub discussion to ExternalEntity
|
|
21
|
+
*
|
|
22
|
+
* @param discussion - GitHub discussion from GraphQL API
|
|
23
|
+
* @param owner - Repository owner
|
|
24
|
+
* @param repo - Repository name
|
|
25
|
+
* @returns ExternalEntity
|
|
26
|
+
*/
|
|
27
|
+
export declare function mapGitHubDiscussionToExternal(discussion: GitHubDiscussion, owner: string, repo: string): ExternalEntity;
|
|
28
|
+
/**
|
|
29
|
+
* Map a GitHub comment to ExternalComment
|
|
30
|
+
*
|
|
31
|
+
* @param comment - GitHub comment from API
|
|
32
|
+
* @returns ExternalComment
|
|
33
|
+
*/
|
|
34
|
+
export declare function mapGitHubCommentToExternal(comment: GitHubComment): ExternalComment;
|
|
35
|
+
/**
|
|
36
|
+
* Map a GitHub discussion comment to ExternalComment
|
|
37
|
+
*
|
|
38
|
+
* @param comment - GitHub discussion comment from GraphQL API
|
|
39
|
+
* @returns ExternalComment
|
|
40
|
+
*/
|
|
41
|
+
export declare function mapGitHubDiscussionCommentToExternal(comment: GitHubDiscussionComment): ExternalComment;
|
|
42
|
+
/**
|
|
43
|
+
* Format content for imported spec with attribution header
|
|
44
|
+
*
|
|
45
|
+
* @param external - External entity to format
|
|
46
|
+
* @returns Formatted content string
|
|
47
|
+
*/
|
|
48
|
+
export declare function formatSpecContent(external: ExternalEntity): string;
|
|
49
|
+
/**
|
|
50
|
+
* Extended spec data including labels for import
|
|
51
|
+
* Note: tags are stored in SpecJSONL, not the base Spec type
|
|
52
|
+
*/
|
|
53
|
+
export interface ImportedSpecData extends Partial<Spec> {
|
|
54
|
+
/** GitHub labels to be stored as tags */
|
|
55
|
+
labels?: string[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Map ExternalEntity to sudocode Spec format
|
|
59
|
+
*
|
|
60
|
+
* @param external - External entity from GitHub
|
|
61
|
+
* @returns Partial Spec for creation/update, with labels stored separately
|
|
62
|
+
*/
|
|
63
|
+
export declare function mapToSudocodeSpec(external: ExternalEntity): ImportedSpecData;
|
|
64
|
+
/**
|
|
65
|
+
* Map priority from sudocode format (0-4) to GitHub labels
|
|
66
|
+
*
|
|
67
|
+
* This is used when pushing back to GitHub (not implemented in this version)
|
|
68
|
+
*
|
|
69
|
+
* @param priority - sudocode priority (0=highest, 4=lowest)
|
|
70
|
+
* @returns GitHub priority label or undefined
|
|
71
|
+
*/
|
|
72
|
+
export declare function mapPriorityToLabel(priority: number): string | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* Extract priority from GitHub labels
|
|
75
|
+
*
|
|
76
|
+
* @param labels - Array of label names
|
|
77
|
+
* @returns Mapped priority (0-4) or undefined
|
|
78
|
+
*/
|
|
79
|
+
export declare function extractPriorityFromLabels(labels: string[]): number | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Build external link metadata for storage
|
|
82
|
+
*
|
|
83
|
+
* @param external - External entity
|
|
84
|
+
* @param entityType - Type of GitHub entity (issue/discussion)
|
|
85
|
+
* @returns External link metadata
|
|
86
|
+
*/
|
|
87
|
+
export declare function buildExternalLinkMetadata(external: ExternalEntity, entityType: GitHubEntityType): Record<string, unknown>;
|
|
88
|
+
//# sourceMappingURL=mappers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../src/mappers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAUhF,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC5G,OAAO,EAAoC,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE1F;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,cAAc,CAmBhB;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,cAAc,CAkBhB;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,aAAa,GAAG,eAAe,CAQlF;AAED;;;;;GAKG;AACH,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,uBAAuB,GAC/B,eAAe,CAQjB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAqBlE;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAiB,SAAQ,OAAO,CAAC,IAAI,CAAC;IACrD,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,cAAc,GAAG,gBAAgB,CAU5E;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CASvE;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CA0B9E;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,gBAAgB,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAazB"}
|
package/dist/mappers.js
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entity mapping utilities for GitHub API → sudocode
|
|
3
|
+
*
|
|
4
|
+
* Converts GitHub API responses to ExternalEntity format
|
|
5
|
+
* and maps to sudocode Spec format.
|
|
6
|
+
*/
|
|
7
|
+
import { formatExternalId } from "./url-parser.js";
|
|
8
|
+
/**
|
|
9
|
+
* Map a GitHub issue to ExternalEntity
|
|
10
|
+
*
|
|
11
|
+
* @param issue - GitHub issue from API
|
|
12
|
+
* @param owner - Repository owner
|
|
13
|
+
* @param repo - Repository name
|
|
14
|
+
* @returns ExternalEntity
|
|
15
|
+
*/
|
|
16
|
+
export function mapGitHubIssueToExternal(issue, owner, repo) {
|
|
17
|
+
return {
|
|
18
|
+
id: formatExternalId(owner, repo, issue.number),
|
|
19
|
+
type: "spec", // GitHub issues map to specs in sudocode
|
|
20
|
+
title: issue.title,
|
|
21
|
+
description: issue.body || "",
|
|
22
|
+
status: issue.state,
|
|
23
|
+
url: issue.html_url,
|
|
24
|
+
created_at: issue.created_at,
|
|
25
|
+
updated_at: issue.updated_at,
|
|
26
|
+
raw: {
|
|
27
|
+
labels: issue.labels.map((l) => l.name),
|
|
28
|
+
author: issue.user?.login,
|
|
29
|
+
comments_count: issue.comments,
|
|
30
|
+
state_reason: issue.state_reason,
|
|
31
|
+
github_id: issue.id,
|
|
32
|
+
entity_type: "issue",
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Map a GitHub discussion to ExternalEntity
|
|
38
|
+
*
|
|
39
|
+
* @param discussion - GitHub discussion from GraphQL API
|
|
40
|
+
* @param owner - Repository owner
|
|
41
|
+
* @param repo - Repository name
|
|
42
|
+
* @returns ExternalEntity
|
|
43
|
+
*/
|
|
44
|
+
export function mapGitHubDiscussionToExternal(discussion, owner, repo) {
|
|
45
|
+
return {
|
|
46
|
+
id: formatExternalId(owner, repo, discussion.number),
|
|
47
|
+
type: "spec",
|
|
48
|
+
title: discussion.title,
|
|
49
|
+
description: discussion.body || "",
|
|
50
|
+
status: "open", // Discussions don't have a closed state like issues
|
|
51
|
+
url: discussion.url,
|
|
52
|
+
created_at: discussion.createdAt,
|
|
53
|
+
updated_at: discussion.updatedAt,
|
|
54
|
+
raw: {
|
|
55
|
+
category: discussion.category.name,
|
|
56
|
+
author: discussion.author?.login,
|
|
57
|
+
comments_count: discussion.comments.totalCount,
|
|
58
|
+
github_id: discussion.id,
|
|
59
|
+
entity_type: "discussion",
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Map a GitHub comment to ExternalComment
|
|
65
|
+
*
|
|
66
|
+
* @param comment - GitHub comment from API
|
|
67
|
+
* @returns ExternalComment
|
|
68
|
+
*/
|
|
69
|
+
export function mapGitHubCommentToExternal(comment) {
|
|
70
|
+
return {
|
|
71
|
+
id: String(comment.id),
|
|
72
|
+
author: comment.user?.login || "unknown",
|
|
73
|
+
body: comment.body,
|
|
74
|
+
created_at: comment.created_at,
|
|
75
|
+
url: comment.html_url,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Map a GitHub discussion comment to ExternalComment
|
|
80
|
+
*
|
|
81
|
+
* @param comment - GitHub discussion comment from GraphQL API
|
|
82
|
+
* @returns ExternalComment
|
|
83
|
+
*/
|
|
84
|
+
export function mapGitHubDiscussionCommentToExternal(comment) {
|
|
85
|
+
return {
|
|
86
|
+
id: comment.id,
|
|
87
|
+
author: comment.author?.login || "unknown",
|
|
88
|
+
body: comment.body,
|
|
89
|
+
created_at: comment.createdAt,
|
|
90
|
+
url: comment.url,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Format content for imported spec with attribution header
|
|
95
|
+
*
|
|
96
|
+
* @param external - External entity to format
|
|
97
|
+
* @returns Formatted content string
|
|
98
|
+
*/
|
|
99
|
+
export function formatSpecContent(external) {
|
|
100
|
+
const lines = [];
|
|
101
|
+
// Add source attribution
|
|
102
|
+
lines.push(`> Imported from [${external.id}](${external.url})`);
|
|
103
|
+
// Add author if available
|
|
104
|
+
const raw = external.raw;
|
|
105
|
+
if (raw?.author) {
|
|
106
|
+
lines.push(`> Author: @${raw.author}`);
|
|
107
|
+
}
|
|
108
|
+
// Add empty line separator
|
|
109
|
+
lines.push("");
|
|
110
|
+
// Add original content
|
|
111
|
+
if (external.description) {
|
|
112
|
+
lines.push(external.description);
|
|
113
|
+
}
|
|
114
|
+
return lines.join("\n");
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Map ExternalEntity to sudocode Spec format
|
|
118
|
+
*
|
|
119
|
+
* @param external - External entity from GitHub
|
|
120
|
+
* @returns Partial Spec for creation/update, with labels stored separately
|
|
121
|
+
*/
|
|
122
|
+
export function mapToSudocodeSpec(external) {
|
|
123
|
+
const raw = external.raw;
|
|
124
|
+
const labels = raw?.labels || [];
|
|
125
|
+
return {
|
|
126
|
+
title: external.title,
|
|
127
|
+
content: formatSpecContent(external),
|
|
128
|
+
priority: 2, // Default priority
|
|
129
|
+
labels, // Stored as labels, caller converts to tags
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Map priority from sudocode format (0-4) to GitHub labels
|
|
134
|
+
*
|
|
135
|
+
* This is used when pushing back to GitHub (not implemented in this version)
|
|
136
|
+
*
|
|
137
|
+
* @param priority - sudocode priority (0=highest, 4=lowest)
|
|
138
|
+
* @returns GitHub priority label or undefined
|
|
139
|
+
*/
|
|
140
|
+
export function mapPriorityToLabel(priority) {
|
|
141
|
+
const labels = {
|
|
142
|
+
0: "priority: critical",
|
|
143
|
+
1: "priority: high",
|
|
144
|
+
2: "priority: medium",
|
|
145
|
+
3: "priority: low",
|
|
146
|
+
4: "priority: lowest",
|
|
147
|
+
};
|
|
148
|
+
return labels[priority];
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Extract priority from GitHub labels
|
|
152
|
+
*
|
|
153
|
+
* @param labels - Array of label names
|
|
154
|
+
* @returns Mapped priority (0-4) or undefined
|
|
155
|
+
*/
|
|
156
|
+
export function extractPriorityFromLabels(labels) {
|
|
157
|
+
const priorityMap = {
|
|
158
|
+
"priority: critical": 0,
|
|
159
|
+
"priority: high": 1,
|
|
160
|
+
"priority: medium": 2,
|
|
161
|
+
"priority: low": 3,
|
|
162
|
+
"priority: lowest": 4,
|
|
163
|
+
"p0": 0,
|
|
164
|
+
"p1": 1,
|
|
165
|
+
"p2": 2,
|
|
166
|
+
"p3": 3,
|
|
167
|
+
"p4": 4,
|
|
168
|
+
"critical": 0,
|
|
169
|
+
"high": 1,
|
|
170
|
+
"medium": 2,
|
|
171
|
+
"low": 3,
|
|
172
|
+
};
|
|
173
|
+
for (const label of labels) {
|
|
174
|
+
const normalized = label.toLowerCase();
|
|
175
|
+
if (normalized in priorityMap) {
|
|
176
|
+
return priorityMap[normalized];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Build external link metadata for storage
|
|
183
|
+
*
|
|
184
|
+
* @param external - External entity
|
|
185
|
+
* @param entityType - Type of GitHub entity (issue/discussion)
|
|
186
|
+
* @returns External link metadata
|
|
187
|
+
*/
|
|
188
|
+
export function buildExternalLinkMetadata(external, entityType) {
|
|
189
|
+
const parsed = external.id.match(/^([\w.-]+)\/([\w.-]+)#(\d+)$/);
|
|
190
|
+
if (!parsed) {
|
|
191
|
+
return { type: entityType };
|
|
192
|
+
}
|
|
193
|
+
const [, owner, repo] = parsed;
|
|
194
|
+
return {
|
|
195
|
+
owner,
|
|
196
|
+
repo,
|
|
197
|
+
type: entityType,
|
|
198
|
+
comments_imported: false,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=mappers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mappers.js","sourceRoot":"","sources":["../src/mappers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URL parsing utilities for GitHub URLs
|
|
3
|
+
*
|
|
4
|
+
* Supports parsing GitHub issue and discussion URLs to extract
|
|
5
|
+
* owner, repo, and entity number.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Supported GitHub URL patterns
|
|
9
|
+
*/
|
|
10
|
+
export declare const GITHUB_URL_PATTERNS: {
|
|
11
|
+
readonly issue: RegExp;
|
|
12
|
+
readonly discussion: RegExp;
|
|
13
|
+
readonly pullRequest: RegExp;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Entity types that can be parsed from GitHub URLs
|
|
17
|
+
*/
|
|
18
|
+
export type GitHubEntityType = "issue" | "discussion" | "pull_request";
|
|
19
|
+
/**
|
|
20
|
+
* Result of parsing a GitHub URL
|
|
21
|
+
*/
|
|
22
|
+
export interface ParsedGitHubUrl {
|
|
23
|
+
/** Repository owner (user or organization) */
|
|
24
|
+
owner: string;
|
|
25
|
+
/** Repository name */
|
|
26
|
+
repo: string;
|
|
27
|
+
/** Entity number (issue/discussion/PR number) */
|
|
28
|
+
number: number;
|
|
29
|
+
/** Type of entity */
|
|
30
|
+
type: GitHubEntityType;
|
|
31
|
+
/** External ID in format "owner/repo#number" */
|
|
32
|
+
externalId: string;
|
|
33
|
+
/** Original URL */
|
|
34
|
+
url: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Check if a URL is a GitHub URL that this provider can handle
|
|
38
|
+
*
|
|
39
|
+
* @param url - URL to check
|
|
40
|
+
* @returns true if URL matches a supported GitHub pattern
|
|
41
|
+
*/
|
|
42
|
+
export declare function canHandleUrl(url: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Parse a GitHub URL to extract entity information
|
|
45
|
+
*
|
|
46
|
+
* @param url - GitHub URL to parse
|
|
47
|
+
* @returns Parsed URL info or null if URL cannot be parsed
|
|
48
|
+
*/
|
|
49
|
+
export declare function parseUrl(url: string): {
|
|
50
|
+
externalId: string;
|
|
51
|
+
metadata?: Record<string, unknown>;
|
|
52
|
+
} | null;
|
|
53
|
+
/**
|
|
54
|
+
* Parse a GitHub URL to extract full details
|
|
55
|
+
*
|
|
56
|
+
* @param url - GitHub URL to parse
|
|
57
|
+
* @returns Full parsed URL details or null if URL cannot be parsed
|
|
58
|
+
*/
|
|
59
|
+
export declare function parseGitHubUrl(url: string): ParsedGitHubUrl | null;
|
|
60
|
+
/**
|
|
61
|
+
* Parse an external ID in format "owner/repo#number"
|
|
62
|
+
*
|
|
63
|
+
* @param externalId - External ID to parse
|
|
64
|
+
* @returns Parsed components or null if invalid format
|
|
65
|
+
*/
|
|
66
|
+
export declare function parseExternalId(externalId: string): {
|
|
67
|
+
owner: string;
|
|
68
|
+
repo: string;
|
|
69
|
+
number: number;
|
|
70
|
+
} | null;
|
|
71
|
+
/**
|
|
72
|
+
* Build a GitHub URL from parsed components
|
|
73
|
+
*
|
|
74
|
+
* @param owner - Repository owner
|
|
75
|
+
* @param repo - Repository name
|
|
76
|
+
* @param number - Entity number
|
|
77
|
+
* @param type - Entity type (defaults to issue)
|
|
78
|
+
* @returns GitHub URL
|
|
79
|
+
*/
|
|
80
|
+
export declare function buildGitHubUrl(owner: string, repo: string, number: number, type?: GitHubEntityType): string;
|
|
81
|
+
/**
|
|
82
|
+
* Format an external ID from components
|
|
83
|
+
*
|
|
84
|
+
* @param owner - Repository owner
|
|
85
|
+
* @param repo - Repository name
|
|
86
|
+
* @param number - Entity number
|
|
87
|
+
* @returns External ID in format "owner/repo#number"
|
|
88
|
+
*/
|
|
89
|
+
export declare function formatExternalId(owner: string, repo: string, number: number): string;
|
|
90
|
+
//# sourceMappingURL=url-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-parser.d.ts","sourceRoot":"","sources":["../src/url-parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;CAItB,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,YAAY,GAAG,cAAc,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,IAAI,EAAE,gBAAgB,CAAC;IACvB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB;IACnB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,MAAM,GACV;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,IAAI,CAkDnE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAqBlE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,GACjB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAYxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,gBAA0B,GAC/B,MAAM,CAQR;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,MAAM,CAER"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URL parsing utilities for GitHub URLs
|
|
3
|
+
*
|
|
4
|
+
* Supports parsing GitHub issue and discussion URLs to extract
|
|
5
|
+
* owner, repo, and entity number.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Supported GitHub URL patterns
|
|
9
|
+
*/
|
|
10
|
+
export const GITHUB_URL_PATTERNS = {
|
|
11
|
+
issue: /^https:\/\/github\.com\/([\w.-]+)\/([\w.-]+)\/issues\/(\d+)(?:\/.*)?(?:\?.*)?(?:#.*)?$/,
|
|
12
|
+
discussion: /^https:\/\/github\.com\/([\w.-]+)\/([\w.-]+)\/discussions\/(\d+)(?:\/.*)?(?:\?.*)?(?:#.*)?$/,
|
|
13
|
+
pullRequest: /^https:\/\/github\.com\/([\w.-]+)\/([\w.-]+)\/pull\/(\d+)(?:\/.*)?(?:\?.*)?(?:#.*)?$/,
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Check if a URL is a GitHub URL that this provider can handle
|
|
17
|
+
*
|
|
18
|
+
* @param url - URL to check
|
|
19
|
+
* @returns true if URL matches a supported GitHub pattern
|
|
20
|
+
*/
|
|
21
|
+
export function canHandleUrl(url) {
|
|
22
|
+
return Object.values(GITHUB_URL_PATTERNS).some((pattern) => pattern.test(url));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parse a GitHub URL to extract entity information
|
|
26
|
+
*
|
|
27
|
+
* @param url - GitHub URL to parse
|
|
28
|
+
* @returns Parsed URL info or null if URL cannot be parsed
|
|
29
|
+
*/
|
|
30
|
+
export function parseUrl(url) {
|
|
31
|
+
// Try issue pattern
|
|
32
|
+
const issueMatch = url.match(GITHUB_URL_PATTERNS.issue);
|
|
33
|
+
if (issueMatch) {
|
|
34
|
+
const [, owner, repo, number] = issueMatch;
|
|
35
|
+
return {
|
|
36
|
+
externalId: `${owner}/${repo}#${number}`,
|
|
37
|
+
metadata: {
|
|
38
|
+
owner,
|
|
39
|
+
repo,
|
|
40
|
+
number: parseInt(number, 10),
|
|
41
|
+
type: "issue",
|
|
42
|
+
url,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// Try discussion pattern
|
|
47
|
+
const discussionMatch = url.match(GITHUB_URL_PATTERNS.discussion);
|
|
48
|
+
if (discussionMatch) {
|
|
49
|
+
const [, owner, repo, number] = discussionMatch;
|
|
50
|
+
return {
|
|
51
|
+
externalId: `${owner}/${repo}#${number}`,
|
|
52
|
+
metadata: {
|
|
53
|
+
owner,
|
|
54
|
+
repo,
|
|
55
|
+
number: parseInt(number, 10),
|
|
56
|
+
type: "discussion",
|
|
57
|
+
url,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// Try PR pattern
|
|
62
|
+
const prMatch = url.match(GITHUB_URL_PATTERNS.pullRequest);
|
|
63
|
+
if (prMatch) {
|
|
64
|
+
const [, owner, repo, number] = prMatch;
|
|
65
|
+
return {
|
|
66
|
+
externalId: `${owner}/${repo}#${number}`,
|
|
67
|
+
metadata: {
|
|
68
|
+
owner,
|
|
69
|
+
repo,
|
|
70
|
+
number: parseInt(number, 10),
|
|
71
|
+
type: "pull_request",
|
|
72
|
+
url,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Parse a GitHub URL to extract full details
|
|
80
|
+
*
|
|
81
|
+
* @param url - GitHub URL to parse
|
|
82
|
+
* @returns Full parsed URL details or null if URL cannot be parsed
|
|
83
|
+
*/
|
|
84
|
+
export function parseGitHubUrl(url) {
|
|
85
|
+
const result = parseUrl(url);
|
|
86
|
+
if (!result || !result.metadata) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
const { owner, repo, number, type } = result.metadata;
|
|
90
|
+
return {
|
|
91
|
+
owner,
|
|
92
|
+
repo,
|
|
93
|
+
number,
|
|
94
|
+
type,
|
|
95
|
+
externalId: result.externalId,
|
|
96
|
+
url,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Parse an external ID in format "owner/repo#number"
|
|
101
|
+
*
|
|
102
|
+
* @param externalId - External ID to parse
|
|
103
|
+
* @returns Parsed components or null if invalid format
|
|
104
|
+
*/
|
|
105
|
+
export function parseExternalId(externalId) {
|
|
106
|
+
const match = externalId.match(/^([\w.-]+)\/([\w.-]+)#(\d+)$/);
|
|
107
|
+
if (!match) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const [, owner, repo, number] = match;
|
|
111
|
+
return {
|
|
112
|
+
owner,
|
|
113
|
+
repo,
|
|
114
|
+
number: parseInt(number, 10),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Build a GitHub URL from parsed components
|
|
119
|
+
*
|
|
120
|
+
* @param owner - Repository owner
|
|
121
|
+
* @param repo - Repository name
|
|
122
|
+
* @param number - Entity number
|
|
123
|
+
* @param type - Entity type (defaults to issue)
|
|
124
|
+
* @returns GitHub URL
|
|
125
|
+
*/
|
|
126
|
+
export function buildGitHubUrl(owner, repo, number, type = "issue") {
|
|
127
|
+
const typeMap = {
|
|
128
|
+
issue: "issues",
|
|
129
|
+
discussion: "discussions",
|
|
130
|
+
pull_request: "pull",
|
|
131
|
+
};
|
|
132
|
+
return `https://github.com/${owner}/${repo}/${typeMap[type]}/${number}`;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Format an external ID from components
|
|
136
|
+
*
|
|
137
|
+
* @param owner - Repository owner
|
|
138
|
+
* @param repo - Repository name
|
|
139
|
+
* @param number - Entity number
|
|
140
|
+
* @returns External ID in format "owner/repo#number"
|
|
141
|
+
*/
|
|
142
|
+
export function formatExternalId(owner, repo, number) {
|
|
143
|
+
return `${owner}/${repo}#${number}`;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=url-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-parser.js","sourceRoot":"","sources":["../src/url-parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,KAAK,EAAE,wFAAwF;IAC/F,UAAU,EAAE,6FAA6F;IACzG,WAAW,EAAE,sFAAsF;CAC3F,CAAC;AAyBX;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,OAAO,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACjF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CACtB,GAAW;IAEX,oBAAoB;IACpB,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACxD,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,UAAU,CAAC;QAC3C,OAAO;YACL,UAAU,EAAE,GAAG,KAAK,IAAI,IAAI,IAAI,MAAM,EAAE;YACxC,QAAQ,EAAE;gBACR,KAAK;gBACL,IAAI;gBACJ,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC5B,IAAI,EAAE,OAA2B;gBACjC,GAAG;aACJ;SACF,CAAC;IACJ,CAAC;IAED,yBAAyB;IACzB,MAAM,eAAe,GAAG,GAAG,CAAC,KAAK,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAClE,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,eAAe,CAAC;QAChD,OAAO;YACL,UAAU,EAAE,GAAG,KAAK,IAAI,IAAI,IAAI,MAAM,EAAE;YACxC,QAAQ,EAAE;gBACR,KAAK;gBACL,IAAI;gBACJ,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC5B,IAAI,EAAE,YAAgC;gBACtC,GAAG;aACJ;SACF,CAAC;IACJ,CAAC;IAED,iBAAiB;IACjB,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC3D,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;QACxC,OAAO;YACL,UAAU,EAAE,GAAG,KAAK,IAAI,IAAI,IAAI,MAAM,EAAE;YACxC,QAAQ,EAAE;gBACR,KAAK;gBACL,IAAI;gBACJ,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC5B,IAAI,EAAE,cAAkC;gBACxC,GAAG;aACJ;SACF,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,QAK5C,CAAC;IAEF,OAAO;QACL,KAAK;QACL,IAAI;QACJ,MAAM;QACN,IAAI;QACJ,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,GAAG;KACJ,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,UAAkB;IAElB,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAC/D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;IACtC,OAAO;QACL,KAAK;QACL,IAAI;QACJ,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;KAC7B,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAa,EACb,IAAY,EACZ,MAAc,EACd,OAAyB,OAAO;IAEhC,MAAM,OAAO,GAAqC;QAChD,KAAK,EAAE,QAAQ;QACf,UAAU,EAAE,aAAa;QACzB,YAAY,EAAE,MAAM;KACrB,CAAC;IAEF,OAAO,sBAAsB,KAAK,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC;AAC1E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAa,EACb,IAAY,EACZ,MAAc;IAEd,OAAO,GAAG,KAAK,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;AACtC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sudocode-ai/integration-github",
|
|
3
|
+
"version": "0.1.14",
|
|
4
|
+
"description": "GitHub integration plugin for sudocode using gh CLI",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"test": "vitest --run",
|
|
20
|
+
"test:cli": "RUN_CLI_TESTS=true vitest --run",
|
|
21
|
+
"clean": "rm -rf dist"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"sudocode",
|
|
25
|
+
"integration",
|
|
26
|
+
"github",
|
|
27
|
+
"plugin",
|
|
28
|
+
"gh-cli"
|
|
29
|
+
],
|
|
30
|
+
"author": "sudocode-ai",
|
|
31
|
+
"license": "Apache-2.0",
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"@sudocode-ai/types": "^0.1.14"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@sudocode-ai/types": "^0.1.14",
|
|
37
|
+
"@types/node": "^22.10.2",
|
|
38
|
+
"typescript": "^5.8.3",
|
|
39
|
+
"vitest": "^3.2.4"
|
|
40
|
+
}
|
|
41
|
+
}
|