@bretwardjames/ghp-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +176 -0
- package/dist/branch-linker.d.ts +15 -0
- package/dist/branch-linker.d.ts.map +1 -0
- package/dist/branch-linker.js +60 -0
- package/dist/branch-linker.js.map +1 -0
- package/dist/commands/add-issue.d.ts +11 -0
- package/dist/commands/add-issue.d.ts.map +1 -0
- package/dist/commands/add-issue.js +228 -0
- package/dist/commands/add-issue.js.map +1 -0
- package/dist/commands/assign.d.ts +6 -0
- package/dist/commands/assign.d.ts.map +1 -0
- package/dist/commands/assign.js +44 -0
- package/dist/commands/assign.js.map +1 -0
- package/dist/commands/auth.d.ts +6 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +31 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/comment.d.ts +6 -0
- package/dist/commands/comment.d.ts.map +1 -0
- package/dist/commands/comment.js +83 -0
- package/dist/commands/comment.js.map +1 -0
- package/dist/commands/config.d.ts +5 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +94 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/done.d.ts +2 -0
- package/dist/commands/done.d.ts.map +1 -0
- package/dist/commands/done.js +54 -0
- package/dist/commands/done.js.map +1 -0
- package/dist/commands/link-branch.d.ts +2 -0
- package/dist/commands/link-branch.d.ts.map +1 -0
- package/dist/commands/link-branch.js +44 -0
- package/dist/commands/link-branch.js.map +1 -0
- package/dist/commands/move.d.ts +2 -0
- package/dist/commands/move.d.ts.map +1 -0
- package/dist/commands/move.js +53 -0
- package/dist/commands/move.js.map +1 -0
- package/dist/commands/open.d.ts +6 -0
- package/dist/commands/open.d.ts.map +1 -0
- package/dist/commands/open.js +189 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/plan.d.ts +2 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +403 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/pr.d.ts +7 -0
- package/dist/commands/pr.d.ts.map +1 -0
- package/dist/commands/pr.js +102 -0
- package/dist/commands/pr.js.map +1 -0
- package/dist/commands/set-field.d.ts +2 -0
- package/dist/commands/set-field.d.ts.map +1 -0
- package/dist/commands/set-field.js +69 -0
- package/dist/commands/set-field.js.map +1 -0
- package/dist/commands/slice.d.ts +8 -0
- package/dist/commands/slice.d.ts.map +1 -0
- package/dist/commands/slice.js +85 -0
- package/dist/commands/slice.js.map +1 -0
- package/dist/commands/start.d.ts +7 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +153 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/switch.d.ts +2 -0
- package/dist/commands/switch.d.ts.map +1 -0
- package/dist/commands/switch.js +44 -0
- package/dist/commands/switch.js.map +1 -0
- package/dist/commands/unlink-branch.d.ts +2 -0
- package/dist/commands/unlink-branch.d.ts.map +1 -0
- package/dist/commands/unlink-branch.js +28 -0
- package/dist/commands/unlink-branch.js.map +1 -0
- package/dist/commands/work.d.ts +9 -0
- package/dist/commands/work.d.ts.map +1 -0
- package/dist/commands/work.js +118 -0
- package/dist/commands/work.js.map +1 -0
- package/dist/config.d.ts +44 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +88 -0
- package/dist/config.js.map +1 -0
- package/dist/git-utils.d.ts +55 -0
- package/dist/git-utils.d.ts.map +1 -0
- package/dist/git-utils.js +140 -0
- package/dist/git-utils.js.map +1 -0
- package/dist/github-api.d.ts +110 -0
- package/dist/github-api.d.ts.map +1 -0
- package/dist/github-api.js +579 -0
- package/dist/github-api.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +149 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +37 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +48 -0
package/dist/config.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
2
|
+
import { homedir } from 'os';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
const CONFIG_DIR = join(homedir(), '.config', 'ghp-cli');
|
|
5
|
+
const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
|
|
6
|
+
const DEFAULT_CONFIG = {
|
|
7
|
+
mainBranch: 'main',
|
|
8
|
+
branchPattern: '{user}/{number}-{title}',
|
|
9
|
+
startWorkingStatus: 'In Progress',
|
|
10
|
+
doneStatus: 'Done',
|
|
11
|
+
defaults: {},
|
|
12
|
+
shortcuts: {},
|
|
13
|
+
};
|
|
14
|
+
export function loadConfig() {
|
|
15
|
+
try {
|
|
16
|
+
if (existsSync(CONFIG_FILE)) {
|
|
17
|
+
const data = readFileSync(CONFIG_FILE, 'utf-8');
|
|
18
|
+
return { ...DEFAULT_CONFIG, ...JSON.parse(data) };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// Ignore errors, use defaults
|
|
23
|
+
}
|
|
24
|
+
return { ...DEFAULT_CONFIG };
|
|
25
|
+
}
|
|
26
|
+
export function saveConfig(config) {
|
|
27
|
+
const current = loadConfig();
|
|
28
|
+
const merged = { ...current, ...config };
|
|
29
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
30
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2));
|
|
33
|
+
}
|
|
34
|
+
export function getConfig(key) {
|
|
35
|
+
const config = loadConfig();
|
|
36
|
+
return config[key];
|
|
37
|
+
}
|
|
38
|
+
export function setConfig(key, value) {
|
|
39
|
+
saveConfig({ [key]: value });
|
|
40
|
+
}
|
|
41
|
+
export function getShortcut(name) {
|
|
42
|
+
const config = loadConfig();
|
|
43
|
+
return config.shortcuts?.[name];
|
|
44
|
+
}
|
|
45
|
+
export function setShortcut(name, shortcut) {
|
|
46
|
+
const config = loadConfig();
|
|
47
|
+
const shortcuts = { ...config.shortcuts, [name]: shortcut };
|
|
48
|
+
saveConfig({ shortcuts });
|
|
49
|
+
}
|
|
50
|
+
export function deleteShortcut(name) {
|
|
51
|
+
const config = loadConfig();
|
|
52
|
+
if (config.shortcuts) {
|
|
53
|
+
delete config.shortcuts[name];
|
|
54
|
+
saveConfig({ shortcuts: config.shortcuts });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export function listShortcuts() {
|
|
58
|
+
const config = loadConfig();
|
|
59
|
+
return config.shortcuts || {};
|
|
60
|
+
}
|
|
61
|
+
export function getPlanDefaults() {
|
|
62
|
+
const config = loadConfig();
|
|
63
|
+
return config.defaults?.plan || {};
|
|
64
|
+
}
|
|
65
|
+
export function setPlanDefaults(defaults) {
|
|
66
|
+
const config = loadConfig();
|
|
67
|
+
saveConfig({
|
|
68
|
+
defaults: { ...config.defaults, plan: defaults }
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
export function getConfigPath() {
|
|
72
|
+
return CONFIG_FILE;
|
|
73
|
+
}
|
|
74
|
+
export function getAddIssueDefaults() {
|
|
75
|
+
const config = loadConfig();
|
|
76
|
+
return config.defaults?.addIssue || {};
|
|
77
|
+
}
|
|
78
|
+
export const CONFIG_KEYS = ['mainBranch', 'branchPattern', 'startWorkingStatus', 'doneStatus'];
|
|
79
|
+
export function listConfig() {
|
|
80
|
+
const config = loadConfig();
|
|
81
|
+
return {
|
|
82
|
+
mainBranch: config.mainBranch,
|
|
83
|
+
branchPattern: config.branchPattern,
|
|
84
|
+
startWorkingStatus: config.startWorkingStatus,
|
|
85
|
+
doneStatus: config.doneStatus,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { RepoInfo } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Detect the GitHub repository from the current directory's git remote
|
|
4
|
+
*/
|
|
5
|
+
export declare function detectRepository(): Promise<RepoInfo | null>;
|
|
6
|
+
/**
|
|
7
|
+
* Parse a GitHub URL into owner and repo name
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseGitHubUrl(url: string): RepoInfo | null;
|
|
10
|
+
/**
|
|
11
|
+
* Get the current git branch
|
|
12
|
+
*/
|
|
13
|
+
export declare function getCurrentBranch(): Promise<string | null>;
|
|
14
|
+
/**
|
|
15
|
+
* Check if there are uncommitted changes
|
|
16
|
+
*/
|
|
17
|
+
export declare function hasUncommittedChanges(): Promise<boolean>;
|
|
18
|
+
/**
|
|
19
|
+
* Check if a branch exists locally
|
|
20
|
+
*/
|
|
21
|
+
export declare function branchExists(branchName: string): Promise<boolean>;
|
|
22
|
+
/**
|
|
23
|
+
* Create and checkout a new branch
|
|
24
|
+
*/
|
|
25
|
+
export declare function createBranch(branchName: string): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Checkout an existing branch
|
|
28
|
+
*/
|
|
29
|
+
export declare function checkoutBranch(branchName: string): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Pull latest from origin
|
|
32
|
+
*/
|
|
33
|
+
export declare function pullLatest(): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Fetch from origin
|
|
36
|
+
*/
|
|
37
|
+
export declare function fetchOrigin(): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Get number of commits behind origin
|
|
40
|
+
*/
|
|
41
|
+
export declare function getCommitsBehind(branch: string): Promise<number>;
|
|
42
|
+
/**
|
|
43
|
+
* Sanitize a string for use in a branch name
|
|
44
|
+
*/
|
|
45
|
+
export declare function sanitizeForBranchName(str: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Generate a branch name from a pattern
|
|
48
|
+
*/
|
|
49
|
+
export declare function generateBranchName(pattern: string, vars: {
|
|
50
|
+
user: string;
|
|
51
|
+
number: number | null;
|
|
52
|
+
title: string;
|
|
53
|
+
repo: string;
|
|
54
|
+
}, maxLength?: number): string;
|
|
55
|
+
//# sourceMappingURL=git-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-utils.d.ts","sourceRoot":"","sources":["../src/git-utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAQjE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAsB3D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAO/D;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO9D;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOvE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEpE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;AAED;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAEhD;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAEjD;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQtE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOzD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAC9B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAC1E,SAAS,GAAE,MAAW,GACvB,MAAM,CAcR"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { exec } from 'child_process';
|
|
2
|
+
import { promisify } from 'util';
|
|
3
|
+
const execAsync = promisify(exec);
|
|
4
|
+
/**
|
|
5
|
+
* Detect the GitHub repository from the current directory's git remote
|
|
6
|
+
*/
|
|
7
|
+
export async function detectRepository() {
|
|
8
|
+
try {
|
|
9
|
+
const { stdout } = await execAsync('git remote get-url origin');
|
|
10
|
+
const url = stdout.trim();
|
|
11
|
+
return parseGitHubUrl(url);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Parse a GitHub URL into owner and repo name
|
|
19
|
+
*/
|
|
20
|
+
export function parseGitHubUrl(url) {
|
|
21
|
+
// Handle SSH format: git@github.com:owner/repo.git
|
|
22
|
+
const sshMatch = url.match(/git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/);
|
|
23
|
+
if (sshMatch) {
|
|
24
|
+
return {
|
|
25
|
+
owner: sshMatch[1],
|
|
26
|
+
name: sshMatch[2],
|
|
27
|
+
fullName: `${sshMatch[1]}/${sshMatch[2]}`,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
// Handle HTTPS format: https://github.com/owner/repo.git
|
|
31
|
+
const httpsMatch = url.match(/https:\/\/github\.com\/([^/]+)\/(.+?)(?:\.git)?$/);
|
|
32
|
+
if (httpsMatch) {
|
|
33
|
+
return {
|
|
34
|
+
owner: httpsMatch[1],
|
|
35
|
+
name: httpsMatch[2],
|
|
36
|
+
fullName: `${httpsMatch[1]}/${httpsMatch[2]}`,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get the current git branch
|
|
43
|
+
*/
|
|
44
|
+
export async function getCurrentBranch() {
|
|
45
|
+
try {
|
|
46
|
+
const { stdout } = await execAsync('git branch --show-current');
|
|
47
|
+
return stdout.trim() || null;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Check if there are uncommitted changes
|
|
55
|
+
*/
|
|
56
|
+
export async function hasUncommittedChanges() {
|
|
57
|
+
try {
|
|
58
|
+
const { stdout } = await execAsync('git status --porcelain');
|
|
59
|
+
return stdout.trim().length > 0;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Check if a branch exists locally
|
|
67
|
+
*/
|
|
68
|
+
export async function branchExists(branchName) {
|
|
69
|
+
try {
|
|
70
|
+
await execAsync(`git show-ref --verify --quiet refs/heads/${branchName}`);
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Create and checkout a new branch
|
|
79
|
+
*/
|
|
80
|
+
export async function createBranch(branchName) {
|
|
81
|
+
await execAsync(`git checkout -b "${branchName}"`);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Checkout an existing branch
|
|
85
|
+
*/
|
|
86
|
+
export async function checkoutBranch(branchName) {
|
|
87
|
+
await execAsync(`git checkout "${branchName}"`);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Pull latest from origin
|
|
91
|
+
*/
|
|
92
|
+
export async function pullLatest() {
|
|
93
|
+
await execAsync('git pull');
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Fetch from origin
|
|
97
|
+
*/
|
|
98
|
+
export async function fetchOrigin() {
|
|
99
|
+
await execAsync('git fetch origin');
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get number of commits behind origin
|
|
103
|
+
*/
|
|
104
|
+
export async function getCommitsBehind(branch) {
|
|
105
|
+
try {
|
|
106
|
+
await fetchOrigin();
|
|
107
|
+
const { stdout } = await execAsync(`git rev-list --count ${branch}..origin/${branch}`);
|
|
108
|
+
return parseInt(stdout.trim(), 10) || 0;
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return 0;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Sanitize a string for use in a branch name
|
|
116
|
+
*/
|
|
117
|
+
export function sanitizeForBranchName(str) {
|
|
118
|
+
return str
|
|
119
|
+
.toLowerCase()
|
|
120
|
+
.replace(/[^a-z0-9-]/g, '-')
|
|
121
|
+
.replace(/-+/g, '-')
|
|
122
|
+
.replace(/^-|-$/g, '')
|
|
123
|
+
.substring(0, 50);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Generate a branch name from a pattern
|
|
127
|
+
*/
|
|
128
|
+
export function generateBranchName(pattern, vars, maxLength = 60) {
|
|
129
|
+
const sanitizedTitle = sanitizeForBranchName(vars.title);
|
|
130
|
+
let branch = pattern
|
|
131
|
+
.replace('{user}', vars.user)
|
|
132
|
+
.replace('{number}', vars.number?.toString() || 'draft')
|
|
133
|
+
.replace('{title}', sanitizedTitle)
|
|
134
|
+
.replace('{repo}', vars.repo);
|
|
135
|
+
if (branch.length > maxLength) {
|
|
136
|
+
branch = branch.substring(0, maxLength).replace(/-$/, '');
|
|
137
|
+
}
|
|
138
|
+
return branch;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=git-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-utils.js","sourceRoot":"","sources":["../src/git-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { RepoInfo, ProjectItem, Project, StatusField } from './types.js';
|
|
2
|
+
export declare class GitHubAPI {
|
|
3
|
+
private graphqlWithAuth;
|
|
4
|
+
username: string | null;
|
|
5
|
+
/**
|
|
6
|
+
* Get token from gh CLI or environment variable
|
|
7
|
+
*/
|
|
8
|
+
getToken(): Promise<string | null>;
|
|
9
|
+
/**
|
|
10
|
+
* Authenticate with GitHub
|
|
11
|
+
*/
|
|
12
|
+
authenticate(): Promise<boolean>;
|
|
13
|
+
get isAuthenticated(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Get projects linked to a repository
|
|
16
|
+
*/
|
|
17
|
+
getProjects(repo: RepoInfo): Promise<Project[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Get items from a project
|
|
20
|
+
*/
|
|
21
|
+
getProjectItems(projectId: string, projectTitle: string): Promise<ProjectItem[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Get the Status field info for a project
|
|
24
|
+
*/
|
|
25
|
+
getStatusField(projectId: string): Promise<StatusField | null>;
|
|
26
|
+
/**
|
|
27
|
+
* Update an item's status
|
|
28
|
+
*/
|
|
29
|
+
updateItemStatus(projectId: string, itemId: string, fieldId: string, optionId: string): Promise<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Find an item by issue number across all projects for this repo
|
|
32
|
+
*/
|
|
33
|
+
findItemByNumber(repo: RepoInfo, issueNumber: number): Promise<ProjectItem | null>;
|
|
34
|
+
/**
|
|
35
|
+
* Get all fields for a project
|
|
36
|
+
*/
|
|
37
|
+
getProjectFields(projectId: string): Promise<Array<{
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
type: string;
|
|
41
|
+
options?: Array<{
|
|
42
|
+
id: string;
|
|
43
|
+
name: string;
|
|
44
|
+
}>;
|
|
45
|
+
}>>;
|
|
46
|
+
/**
|
|
47
|
+
* Set a field value on a project item
|
|
48
|
+
*/
|
|
49
|
+
setFieldValue(projectId: string, itemId: string, fieldId: string, value: {
|
|
50
|
+
text?: string;
|
|
51
|
+
number?: number;
|
|
52
|
+
singleSelectOptionId?: string;
|
|
53
|
+
}): Promise<boolean>;
|
|
54
|
+
/**
|
|
55
|
+
* Create a new issue
|
|
56
|
+
*/
|
|
57
|
+
createIssue(repo: RepoInfo, title: string, body?: string): Promise<{
|
|
58
|
+
id: string;
|
|
59
|
+
number: number;
|
|
60
|
+
} | null>;
|
|
61
|
+
/**
|
|
62
|
+
* Add an issue to a project
|
|
63
|
+
*/
|
|
64
|
+
addToProject(projectId: string, contentId: string): Promise<string | null>;
|
|
65
|
+
/**
|
|
66
|
+
* Get full issue details including body and comments
|
|
67
|
+
*/
|
|
68
|
+
getIssueDetails(repo: RepoInfo, issueNumber: number): Promise<IssueDetails | null>;
|
|
69
|
+
/**
|
|
70
|
+
* Add a comment to an issue or PR
|
|
71
|
+
*/
|
|
72
|
+
addComment(repo: RepoInfo, issueNumber: number, body: string): Promise<boolean>;
|
|
73
|
+
/**
|
|
74
|
+
* Get repository collaborators (for @ mention suggestions)
|
|
75
|
+
*/
|
|
76
|
+
getCollaborators(repo: RepoInfo): Promise<Collaborator[]>;
|
|
77
|
+
/**
|
|
78
|
+
* Get recent issues (for # reference suggestions)
|
|
79
|
+
*/
|
|
80
|
+
getRecentIssues(repo: RepoInfo, limit?: number): Promise<IssueReference[]>;
|
|
81
|
+
}
|
|
82
|
+
export interface IssueDetails {
|
|
83
|
+
title: string;
|
|
84
|
+
body: string;
|
|
85
|
+
state: string;
|
|
86
|
+
type: 'issue' | 'pull_request';
|
|
87
|
+
createdAt: string;
|
|
88
|
+
author: string;
|
|
89
|
+
labels: Array<{
|
|
90
|
+
name: string;
|
|
91
|
+
color: string;
|
|
92
|
+
}>;
|
|
93
|
+
comments: Array<{
|
|
94
|
+
author: string;
|
|
95
|
+
body: string;
|
|
96
|
+
createdAt: string;
|
|
97
|
+
}>;
|
|
98
|
+
totalComments: number;
|
|
99
|
+
}
|
|
100
|
+
export interface Collaborator {
|
|
101
|
+
login: string;
|
|
102
|
+
name: string | null;
|
|
103
|
+
}
|
|
104
|
+
export interface IssueReference {
|
|
105
|
+
number: number;
|
|
106
|
+
title: string;
|
|
107
|
+
state: string;
|
|
108
|
+
}
|
|
109
|
+
export declare const api: GitHubAPI;
|
|
110
|
+
//# sourceMappingURL=github-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-api.d.ts","sourceRoot":"","sources":["../src/github-api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI9E,qBAAa,SAAS;IAClB,OAAO,CAAC,eAAe,CAA+B;IAC/C,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEtC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAkBxC;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IA6BtC,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAmCrD;;OAEG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAgJtF;;OAEG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IA6CpE;;OAEG;IACG,gBAAgB,CAClB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC;IAuBnB;;OAEG;IACG,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAYxF;;OAEG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QACrD,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACjD,CAAC,CAAC;IAiDH;;OAEG;IACG,aAAa,CACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,KAAK,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,oBAAoB,CAAC,EAAE,MAAM,CAAA;KAAE,GACzE,OAAO,CAAC,OAAO,CAAC;IAuBnB;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IA2C/G;;OAEG;IACG,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAwBhF;;OAEG;IACG,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IA8FxF;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA+CrF;;OAEG;IACG,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAsC/D;;OAEG;IACG,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;CAiCvF;AAED,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,QAAQ,EAAE,KAAK,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;IACH,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACjB;AAGD,eAAO,MAAM,GAAG,WAAkB,CAAC"}
|