@ghfs/cli 0.0.1 → 0.0.2

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.
@@ -0,0 +1,428 @@
1
+ import { retry } from "@octokit/plugin-retry";
2
+ import { throttling } from "@octokit/plugin-throttling";
3
+ import { Octokit } from "octokit";
4
+
5
+ //#region src/utils/repo.ts
6
+ function splitRepo(repo) {
7
+ const [owner, name] = repo.split("/");
8
+ if (!owner || !name) throw new Error(`Invalid repo slug: ${repo}`);
9
+ return {
10
+ owner,
11
+ repo: name
12
+ };
13
+ }
14
+
15
+ //#endregion
16
+ //#region src/providers/helpers.ts
17
+ async function collectPages(pages) {
18
+ const items = [];
19
+ for await (const page of pages) items.push(...page);
20
+ return items;
21
+ }
22
+ async function* iteratePages(pages) {
23
+ for await (const page of pages) for (const item of page) yield item;
24
+ }
25
+
26
+ //#endregion
27
+ //#region src/providers/github/client.ts
28
+ const BaseOctokit = Octokit.plugin(retry, throttling);
29
+ function createGitHubClient(token) {
30
+ return new BaseOctokit({
31
+ auth: token,
32
+ throttle: {
33
+ onRateLimit: (retryAfter, options) => {
34
+ if ((options.request.retryCount ?? 0) < 2) return true;
35
+ return false;
36
+ },
37
+ onSecondaryRateLimit: () => {
38
+ return false;
39
+ }
40
+ },
41
+ retry: {
42
+ doNotRetry: [401, 403],
43
+ retries: 2
44
+ }
45
+ });
46
+ }
47
+
48
+ //#endregion
49
+ //#region src/providers/github/provider.ts
50
+ function createGitHubProvider(options) {
51
+ const octokit = createGitHubClient(options.token);
52
+ const { owner, repo } = options;
53
+ let requestCount = 0;
54
+ const bumpRequestCount = () => {
55
+ requestCount += 1;
56
+ };
57
+ return {
58
+ paginateItems: (paginateOptions) => paginateItems(octokit, owner, repo, paginateOptions, bumpRequestCount),
59
+ fetchItems: (paginateOptions) => fetchItems(octokit, owner, repo, paginateOptions, bumpRequestCount),
60
+ eachItem: (paginateOptions) => eachItem(octokit, owner, repo, paginateOptions, bumpRequestCount),
61
+ fetchItemsByNumbers: (numbers) => fetchItemsByNumbers(octokit, owner, repo, numbers, bumpRequestCount),
62
+ fetchComments: (number) => fetchComments(octokit, owner, repo, number, bumpRequestCount),
63
+ fetchPullMetadata: (number) => fetchPullMetadata(octokit, owner, repo, number, bumpRequestCount),
64
+ fetchPullPatch: (number) => fetchPullPatch(octokit, owner, repo, number, bumpRequestCount),
65
+ fetchItemSnapshot: (number) => fetchItemSnapshot(octokit, owner, repo, number, bumpRequestCount),
66
+ fetchRepository: () => fetchRepository(octokit, owner, repo, bumpRequestCount),
67
+ fetchRepositoryLabels: () => fetchRepositoryLabels(octokit, owner, repo, bumpRequestCount),
68
+ fetchRepositoryMilestones: () => fetchRepositoryMilestones(octokit, owner, repo, bumpRequestCount),
69
+ getRequestCount: () => requestCount,
70
+ actionClose: (number) => actionClose(octokit, owner, repo, number, bumpRequestCount),
71
+ actionReopen: (number) => actionReopen(octokit, owner, repo, number, bumpRequestCount),
72
+ actionSetTitle: (number, title) => actionSetTitle(octokit, owner, repo, number, title, bumpRequestCount),
73
+ actionSetBody: (number, body) => actionSetBody(octokit, owner, repo, number, body, bumpRequestCount),
74
+ actionAddComment: (number, body) => actionAddComment(octokit, owner, repo, number, body, bumpRequestCount),
75
+ actionAddLabels: (number, labels) => actionAddLabels(octokit, owner, repo, number, labels, bumpRequestCount),
76
+ actionRemoveLabels: (number, labels) => actionRemoveLabels(octokit, owner, repo, number, labels, bumpRequestCount),
77
+ actionSetLabels: (number, labels) => actionSetLabels(octokit, owner, repo, number, labels, bumpRequestCount),
78
+ actionAddAssignees: (number, assignees) => actionAddAssignees(octokit, owner, repo, number, assignees, bumpRequestCount),
79
+ actionRemoveAssignees: (number, assignees) => actionRemoveAssignees(octokit, owner, repo, number, assignees, bumpRequestCount),
80
+ actionSetAssignees: (number, assignees) => actionSetAssignees(octokit, owner, repo, number, assignees, bumpRequestCount),
81
+ actionSetMilestone: (number, milestone) => actionSetMilestone(octokit, owner, repo, number, milestone, bumpRequestCount),
82
+ actionClearMilestone: (number) => actionClearMilestone(octokit, owner, repo, number, bumpRequestCount),
83
+ actionLock: (number, reason) => actionLock(octokit, owner, repo, number, reason, bumpRequestCount),
84
+ actionUnlock: (number) => actionUnlock(octokit, owner, repo, number, bumpRequestCount),
85
+ actionRequestReviewers: (number, reviewers) => actionRequestReviewers(octokit, owner, repo, number, reviewers, bumpRequestCount),
86
+ actionRemoveReviewers: (number, reviewers) => actionRemoveReviewers(octokit, owner, repo, number, reviewers, bumpRequestCount),
87
+ actionMarkReadyForReview: (number) => actionMarkReadyForReview(octokit, owner, repo, number, bumpRequestCount),
88
+ actionConvertToDraft: (number) => actionConvertToDraft(octokit, owner, repo, number, bumpRequestCount)
89
+ };
90
+ }
91
+ async function* paginateItems(octokit, owner, repo, options, bumpRequestCount) {
92
+ const iterator = octokit.paginate.iterator(octokit.rest.issues.listForRepo, {
93
+ owner,
94
+ repo,
95
+ state: options.state,
96
+ sort: "updated",
97
+ direction: "asc",
98
+ per_page: 100,
99
+ since: options.since
100
+ });
101
+ for await (const page of iterator) {
102
+ bumpRequestCount();
103
+ yield page.data.map(mapIssue);
104
+ }
105
+ }
106
+ async function fetchItems(octokit, owner, repo, options, bumpRequestCount) {
107
+ return await collectPages(paginateItems(octokit, owner, repo, options, bumpRequestCount));
108
+ }
109
+ async function* eachItem(octokit, owner, repo, options, bumpRequestCount) {
110
+ yield* iteratePages(paginateItems(octokit, owner, repo, options, bumpRequestCount));
111
+ }
112
+ async function fetchItemsByNumbers(octokit, owner, repo, numbers, bumpRequestCount) {
113
+ return (await Promise.all(numbers.map(async (number) => {
114
+ bumpRequestCount();
115
+ return mapIssue((await octokit.rest.issues.get({
116
+ owner,
117
+ repo,
118
+ issue_number: number
119
+ })).data);
120
+ }))).sort((a, b) => a.number - b.number);
121
+ }
122
+ async function fetchComments(octokit, owner, repo, number, bumpRequestCount) {
123
+ bumpRequestCount();
124
+ return (await octokit.paginate(octokit.rest.issues.listComments, {
125
+ owner,
126
+ repo,
127
+ issue_number: number,
128
+ per_page: 100
129
+ })).map(mapComment);
130
+ }
131
+ async function fetchPullMetadata(octokit, owner, repo, number, bumpRequestCount) {
132
+ bumpRequestCount();
133
+ const pull = (await octokit.rest.pulls.get({
134
+ owner,
135
+ repo,
136
+ pull_number: number
137
+ })).data;
138
+ return {
139
+ isDraft: pull.draft,
140
+ merged: pull.merged,
141
+ mergedAt: pull.merged_at,
142
+ baseRef: pull.base.ref,
143
+ headRef: pull.head.ref,
144
+ requestedReviewers: pull.requested_reviewers.map((reviewer) => reviewer.login)
145
+ };
146
+ }
147
+ async function fetchPullPatch(octokit, owner, repo, number, bumpRequestCount) {
148
+ bumpRequestCount();
149
+ const result = await octokit.request("GET /repos/{owner}/{repo}/pulls/{pull_number}", {
150
+ owner,
151
+ repo,
152
+ pull_number: number,
153
+ mediaType: { format: "patch" }
154
+ });
155
+ if (typeof result.data === "string") return result.data;
156
+ throw new Error(`Unexpected patch response for pull #${number}`);
157
+ }
158
+ async function fetchItemSnapshot(octokit, owner, repo, number, bumpRequestCount) {
159
+ bumpRequestCount();
160
+ const issue = (await octokit.rest.issues.get({
161
+ owner,
162
+ repo,
163
+ issue_number: number
164
+ })).data;
165
+ return {
166
+ number,
167
+ kind: issue.pull_request ? "pull" : "issue",
168
+ updatedAt: issue.updated_at ?? null
169
+ };
170
+ }
171
+ async function fetchRepository(octokit, owner, repo, bumpRequestCount) {
172
+ bumpRequestCount();
173
+ return (await octokit.rest.repos.get({
174
+ owner,
175
+ repo
176
+ })).data;
177
+ }
178
+ async function fetchRepositoryLabels(octokit, owner, repo, bumpRequestCount) {
179
+ bumpRequestCount();
180
+ return await octokit.paginate(octokit.rest.issues.listLabelsForRepo, {
181
+ owner,
182
+ repo,
183
+ per_page: 100
184
+ });
185
+ }
186
+ async function fetchRepositoryMilestones(octokit, owner, repo, bumpRequestCount) {
187
+ bumpRequestCount();
188
+ return await octokit.paginate(octokit.rest.issues.listMilestones, {
189
+ owner,
190
+ repo,
191
+ state: "all",
192
+ per_page: 100
193
+ });
194
+ }
195
+ async function actionClose(octokit, owner, repo, number, bumpRequestCount) {
196
+ bumpRequestCount();
197
+ await octokit.rest.issues.update({
198
+ owner,
199
+ repo,
200
+ issue_number: number,
201
+ state: "closed"
202
+ });
203
+ }
204
+ async function actionReopen(octokit, owner, repo, number, bumpRequestCount) {
205
+ bumpRequestCount();
206
+ await octokit.rest.issues.update({
207
+ owner,
208
+ repo,
209
+ issue_number: number,
210
+ state: "open"
211
+ });
212
+ }
213
+ async function actionSetTitle(octokit, owner, repo, number, title, bumpRequestCount) {
214
+ bumpRequestCount();
215
+ await octokit.rest.issues.update({
216
+ owner,
217
+ repo,
218
+ issue_number: number,
219
+ title
220
+ });
221
+ }
222
+ async function actionSetBody(octokit, owner, repo, number, body, bumpRequestCount) {
223
+ bumpRequestCount();
224
+ await octokit.rest.issues.update({
225
+ owner,
226
+ repo,
227
+ issue_number: number,
228
+ body
229
+ });
230
+ }
231
+ async function actionAddComment(octokit, owner, repo, number, body, bumpRequestCount) {
232
+ bumpRequestCount();
233
+ await octokit.rest.issues.createComment({
234
+ owner,
235
+ repo,
236
+ issue_number: number,
237
+ body
238
+ });
239
+ }
240
+ async function actionAddLabels(octokit, owner, repo, number, labels, bumpRequestCount) {
241
+ bumpRequestCount();
242
+ await octokit.rest.issues.addLabels({
243
+ owner,
244
+ repo,
245
+ issue_number: number,
246
+ labels
247
+ });
248
+ }
249
+ async function actionRemoveLabels(octokit, owner, repo, number, labels, bumpRequestCount) {
250
+ for (const label of labels) try {
251
+ bumpRequestCount();
252
+ await octokit.rest.issues.removeLabel({
253
+ owner,
254
+ repo,
255
+ issue_number: number,
256
+ name: label
257
+ });
258
+ } catch (error) {
259
+ if (error.status !== 404) throw error;
260
+ }
261
+ }
262
+ async function actionSetLabels(octokit, owner, repo, number, labels, bumpRequestCount) {
263
+ bumpRequestCount();
264
+ await octokit.rest.issues.setLabels({
265
+ owner,
266
+ repo,
267
+ issue_number: number,
268
+ labels
269
+ });
270
+ }
271
+ async function actionAddAssignees(octokit, owner, repo, number, assignees, bumpRequestCount) {
272
+ bumpRequestCount();
273
+ await octokit.rest.issues.addAssignees({
274
+ owner,
275
+ repo,
276
+ issue_number: number,
277
+ assignees
278
+ });
279
+ }
280
+ async function actionRemoveAssignees(octokit, owner, repo, number, assignees, bumpRequestCount) {
281
+ bumpRequestCount();
282
+ await octokit.rest.issues.removeAssignees({
283
+ owner,
284
+ repo,
285
+ issue_number: number,
286
+ assignees
287
+ });
288
+ }
289
+ async function actionSetAssignees(octokit, owner, repo, number, assignees, bumpRequestCount) {
290
+ bumpRequestCount();
291
+ await octokit.rest.issues.update({
292
+ owner,
293
+ repo,
294
+ issue_number: number,
295
+ assignees
296
+ });
297
+ }
298
+ async function actionSetMilestone(octokit, owner, repo, number, milestone, bumpRequestCount) {
299
+ const resolvedMilestone = await resolveMilestone(octokit, owner, repo, milestone, bumpRequestCount);
300
+ bumpRequestCount();
301
+ await octokit.rest.issues.update({
302
+ owner,
303
+ repo,
304
+ issue_number: number,
305
+ milestone: resolvedMilestone
306
+ });
307
+ }
308
+ async function actionClearMilestone(octokit, owner, repo, number, bumpRequestCount) {
309
+ bumpRequestCount();
310
+ await octokit.rest.issues.update({
311
+ owner,
312
+ repo,
313
+ issue_number: number,
314
+ milestone: null
315
+ });
316
+ }
317
+ async function actionLock(octokit, owner, repo, number, reason, bumpRequestCount) {
318
+ bumpRequestCount();
319
+ await octokit.rest.issues.lock({
320
+ owner,
321
+ repo,
322
+ issue_number: number,
323
+ lock_reason: normalizeLockReason(reason)
324
+ });
325
+ }
326
+ async function actionUnlock(octokit, owner, repo, number, bumpRequestCount) {
327
+ bumpRequestCount();
328
+ await octokit.rest.issues.unlock({
329
+ owner,
330
+ repo,
331
+ issue_number: number
332
+ });
333
+ }
334
+ async function actionRequestReviewers(octokit, owner, repo, number, reviewers, bumpRequestCount) {
335
+ bumpRequestCount();
336
+ await octokit.rest.pulls.requestReviewers({
337
+ owner,
338
+ repo,
339
+ pull_number: number,
340
+ reviewers
341
+ });
342
+ }
343
+ async function actionRemoveReviewers(octokit, owner, repo, number, reviewers, bumpRequestCount) {
344
+ bumpRequestCount();
345
+ await octokit.rest.pulls.removeRequestedReviewers({
346
+ owner,
347
+ repo,
348
+ pull_number: number,
349
+ reviewers
350
+ });
351
+ }
352
+ async function actionMarkReadyForReview(octokit, owner, repo, number, bumpRequestCount) {
353
+ bumpRequestCount();
354
+ await octokit.request("POST /repos/{owner}/{repo}/pulls/{pull_number}/ready_for_review", {
355
+ owner,
356
+ repo,
357
+ pull_number: number
358
+ });
359
+ }
360
+ async function actionConvertToDraft(octokit, owner, repo, number, bumpRequestCount) {
361
+ bumpRequestCount();
362
+ await octokit.request("POST /repos/{owner}/{repo}/pulls/{pull_number}/convert-to-draft", {
363
+ owner,
364
+ repo,
365
+ pull_number: number
366
+ });
367
+ }
368
+ async function resolveMilestone(octokit, owner, repo, value, bumpRequestCount) {
369
+ if (typeof value === "number") return value;
370
+ if (/^\d+$/.test(value)) return Number(value);
371
+ bumpRequestCount();
372
+ const matched = (await octokit.paginate(octokit.rest.issues.listMilestones, {
373
+ owner,
374
+ repo,
375
+ state: "all",
376
+ per_page: 100
377
+ })).find((item) => item.title === value);
378
+ if (!matched) throw new Error(`Milestone not found: ${value}`);
379
+ return matched.number;
380
+ }
381
+ function normalizeLockReason(reason) {
382
+ if (!reason) return void 0;
383
+ if (reason === "too-heated") return "too heated";
384
+ return reason;
385
+ }
386
+ function mapIssue(issue) {
387
+ return {
388
+ number: issue.number,
389
+ kind: issue.pull_request ? "pull" : "issue",
390
+ ...issue.html_url ? { url: issue.html_url } : {},
391
+ state: issue.state === "closed" ? "closed" : "open",
392
+ updatedAt: issue.updated_at,
393
+ createdAt: issue.created_at,
394
+ closedAt: issue.closed_at,
395
+ title: issue.title,
396
+ body: issue.body,
397
+ author: issue.user?.login ?? null,
398
+ labels: issue.labels.map((label) => {
399
+ if (typeof label === "string") return label;
400
+ return label.name ?? void 0;
401
+ }).filter((label) => Boolean(label)),
402
+ assignees: (issue.assignees ?? []).map((assignee) => assignee.login),
403
+ milestone: issue.milestone?.title ?? null
404
+ };
405
+ }
406
+ function mapComment(comment) {
407
+ return {
408
+ id: comment.id,
409
+ body: comment.body,
410
+ createdAt: comment.created_at,
411
+ updatedAt: comment.updated_at,
412
+ author: comment.user?.login ?? null
413
+ };
414
+ }
415
+
416
+ //#endregion
417
+ //#region src/providers/factory.ts
418
+ function createRepositoryProvider(options) {
419
+ const { owner, repo } = splitRepo(options.repo);
420
+ return createGitHubProvider({
421
+ token: options.token,
422
+ owner,
423
+ repo
424
+ });
425
+ }
426
+
427
+ //#endregion
428
+ export { createRepositoryProvider as t };
@@ -0,0 +1,194 @@
1
+ //#region src/types/config.d.ts
2
+ interface GhfsUserConfig {
3
+ /**
4
+ * The repository to sync.
5
+ *
6
+ * Will try to detect the repository from the current working directory or the `package.json` file.
7
+ */
8
+ repo?: string;
9
+ /**
10
+ * The directory to store the synced issues and pull requests.
11
+ *
12
+ * @default '.ghfs'
13
+ */
14
+ directory?: string;
15
+ /**
16
+ * The authentication configuration.
17
+ */
18
+ auth?: {
19
+ /**
20
+ * The GitHub personal access token to use for authentication.
21
+ *
22
+ * When not provided, will try to get the token from `gh auth token` or the environment variables `GH_TOKEN` or `GITHUB_TOKEN`.
23
+ */
24
+ token?: string;
25
+ };
26
+ sync?: {
27
+ /**
28
+ * Whether to sync issues.
29
+ *
30
+ * @default true
31
+ */
32
+ issues?: boolean;
33
+ /**
34
+ * Whether to sync pull requests.
35
+ *
36
+ * @default true
37
+ */
38
+ pulls?: boolean;
39
+ /**
40
+ * When to sync closed issues and pull requests.
41
+ *
42
+ * - `'existing'`: only sync closed issues and pull requests that already exist in the local filesystem.
43
+ * - `'all'`: sync all closed issues and pull requests.
44
+ * - `false`: don't sync any closed issues and pull requests. And delete any existing closed issues and pull requests from the local filesystem.
45
+ *
46
+ * @default 'existing'
47
+ */
48
+ closed?: 'existing' | 'all' | false;
49
+ /**
50
+ * When to download the pull request patch files.
51
+ *
52
+ * - `'open'`: only download open pull request patch files.
53
+ * - `'all'`: download all pull request patch files.
54
+ * - `false`: don't download any pull request patch files.
55
+ *
56
+ * @default 'open'
57
+ */
58
+ patches?: 'open' | 'all' | false;
59
+ };
60
+ }
61
+ type GhfsResolvedConfig = Required<GhfsUserConfig> & {
62
+ cwd: string;
63
+ auth: Required<GhfsUserConfig['auth']>;
64
+ sync: Required<GhfsUserConfig['sync']>;
65
+ };
66
+ //#endregion
67
+ //#region src/types/issue.d.ts
68
+ type IssueKind = 'issue' | 'pull';
69
+ type IssueState = 'open' | 'closed';
70
+ //#endregion
71
+ //#region src/types/provider.d.ts
72
+ interface ProviderItem {
73
+ number: number;
74
+ kind: IssueKind;
75
+ url?: string;
76
+ state: IssueState;
77
+ updatedAt: string;
78
+ createdAt: string;
79
+ closedAt: string | null;
80
+ title: string;
81
+ body: string | null;
82
+ author: string | null;
83
+ labels: string[];
84
+ assignees: string[];
85
+ milestone: string | null;
86
+ }
87
+ interface ProviderComment {
88
+ id: number;
89
+ body: string | null;
90
+ createdAt: string;
91
+ updatedAt: string;
92
+ author: string | null;
93
+ }
94
+ interface ProviderPullMetadata {
95
+ isDraft: boolean;
96
+ merged: boolean;
97
+ mergedAt: string | null;
98
+ baseRef: string;
99
+ headRef: string;
100
+ requestedReviewers: string[];
101
+ }
102
+ interface ProviderRepository {
103
+ name: string;
104
+ full_name: string;
105
+ description: string | null;
106
+ private: boolean;
107
+ archived: boolean;
108
+ default_branch: string;
109
+ html_url: string;
110
+ fork: boolean;
111
+ open_issues_count: number;
112
+ has_issues: boolean;
113
+ has_projects: boolean;
114
+ has_wiki: boolean;
115
+ created_at: string;
116
+ updated_at: string;
117
+ pushed_at: string | null;
118
+ owner: {
119
+ login: string;
120
+ };
121
+ }
122
+ interface ProviderLabel {
123
+ name: string;
124
+ color: string;
125
+ description: string | null;
126
+ default: boolean;
127
+ }
128
+ interface ProviderMilestone {
129
+ number: number;
130
+ title: string;
131
+ state: 'open' | 'closed';
132
+ description: string | null;
133
+ due_on: string | null;
134
+ open_issues: number;
135
+ closed_issues: number;
136
+ created_at: string;
137
+ updated_at: string;
138
+ closed_at: string | null;
139
+ }
140
+ interface ProviderItemSnapshot {
141
+ number: number;
142
+ kind: IssueKind;
143
+ updatedAt: string | null;
144
+ }
145
+ type ProviderLockReason = 'resolved' | 'off-topic' | 'too heated' | 'too-heated' | 'spam';
146
+ interface PaginateItemsOptions {
147
+ state: IssueState | 'all';
148
+ since?: string;
149
+ }
150
+ interface RepositoryProvider {
151
+ paginateItems: (options: PaginateItemsOptions) => AsyncIterable<ProviderItem[]>;
152
+ fetchItems: (options: PaginateItemsOptions) => Promise<ProviderItem[]>;
153
+ eachItem: (options: PaginateItemsOptions) => AsyncIterable<ProviderItem>;
154
+ fetchItemsByNumbers: (numbers: number[]) => Promise<ProviderItem[]>;
155
+ fetchComments: (number: number) => Promise<ProviderComment[]>;
156
+ fetchPullMetadata: (number: number) => Promise<ProviderPullMetadata>;
157
+ fetchPullPatch: (number: number) => Promise<string>;
158
+ fetchItemSnapshot: (number: number) => Promise<ProviderItemSnapshot>;
159
+ fetchRepository: () => Promise<ProviderRepository>;
160
+ fetchRepositoryLabels: () => Promise<ProviderLabel[]>;
161
+ fetchRepositoryMilestones: () => Promise<ProviderMilestone[]>;
162
+ getRequestCount: () => number;
163
+ actionClose: (number: number) => Promise<void>;
164
+ actionReopen: (number: number) => Promise<void>;
165
+ actionSetTitle: (number: number, title: string) => Promise<void>;
166
+ actionSetBody: (number: number, body: string) => Promise<void>;
167
+ actionAddComment: (number: number, body: string) => Promise<void>;
168
+ actionAddLabels: (number: number, labels: string[]) => Promise<void>;
169
+ actionRemoveLabels: (number: number, labels: string[]) => Promise<void>;
170
+ actionSetLabels: (number: number, labels: string[]) => Promise<void>;
171
+ actionAddAssignees: (number: number, assignees: string[]) => Promise<void>;
172
+ actionRemoveAssignees: (number: number, assignees: string[]) => Promise<void>;
173
+ actionSetAssignees: (number: number, assignees: string[]) => Promise<void>;
174
+ actionSetMilestone: (number: number, milestone: string | number) => Promise<void>;
175
+ actionClearMilestone: (number: number) => Promise<void>;
176
+ actionLock: (number: number, reason?: ProviderLockReason) => Promise<void>;
177
+ actionUnlock: (number: number) => Promise<void>;
178
+ actionRequestReviewers: (number: number, reviewers: string[]) => Promise<void>;
179
+ actionRemoveReviewers: (number: number, reviewers: string[]) => Promise<void>;
180
+ actionMarkReadyForReview: (number: number) => Promise<void>;
181
+ actionConvertToDraft: (number: number) => Promise<void>;
182
+ }
183
+ //#endregion
184
+ //#region src/providers/factory.d.ts
185
+ interface CreateRepositoryProviderOptions {
186
+ token: string;
187
+ repo: string;
188
+ }
189
+ declare function createRepositoryProvider(options: CreateRepositoryProviderOptions): RepositoryProvider;
190
+ //#endregion
191
+ //#region src/index.d.ts
192
+ declare function defineConfig(config: GhfsUserConfig): GhfsUserConfig;
193
+ //#endregion
194
+ export { type GhfsResolvedConfig, type GhfsUserConfig, type IssueKind, type IssueState, type PaginateItemsOptions, type ProviderComment, type ProviderItem, type ProviderItemSnapshot, type ProviderLockReason, type ProviderPullMetadata, type RepositoryProvider, createRepositoryProvider, defineConfig };
package/dist/index.mjs ADDED
@@ -0,0 +1,9 @@
1
+ import { t as createRepositoryProvider } from "./factory-CNz1r4PQ.mjs";
2
+
3
+ //#region src/index.ts
4
+ function defineConfig(config) {
5
+ return config;
6
+ }
7
+
8
+ //#endregion
9
+ export { createRepositoryProvider, defineConfig };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ghfs/cli",
3
3
  "type": "module",
4
- "version": "0.0.1",
4
+ "version": "0.0.2",
5
5
  "description": "GitHub issues/PRs as filesystem, for offline view and operations in batch. Designed for human and agents.",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",