@sascha384/tic 3.0.0 → 4.0.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.
Files changed (43) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dist/auth/gitlab.d.ts +37 -0
  3. package/dist/auth/gitlab.js +111 -0
  4. package/dist/auth/gitlab.js.map +1 -0
  5. package/dist/backends/availability.js +1 -1
  6. package/dist/backends/availability.js.map +1 -1
  7. package/dist/backends/factory.js +1 -1
  8. package/dist/backends/factory.js.map +1 -1
  9. package/dist/backends/gitlab/api.d.ts +14 -0
  10. package/dist/backends/gitlab/api.js +53 -0
  11. package/dist/backends/gitlab/api.js.map +1 -0
  12. package/dist/backends/gitlab/index.d.ts +15 -13
  13. package/dist/backends/gitlab/index.js +425 -357
  14. package/dist/backends/gitlab/index.js.map +1 -1
  15. package/dist/backends/gitlab/mappers.d.ts +50 -28
  16. package/dist/backends/gitlab/mappers.js +30 -31
  17. package/dist/backends/gitlab/mappers.js.map +1 -1
  18. package/dist/backends/gitlab/remote.d.ts +7 -0
  19. package/dist/backends/gitlab/remote.js +32 -0
  20. package/dist/backends/gitlab/remote.js.map +1 -0
  21. package/dist/cli/commands/auth.d.ts +1 -1
  22. package/dist/cli/commands/auth.js +24 -2
  23. package/dist/cli/commands/auth.js.map +1 -1
  24. package/dist/cli/index.js +2 -2
  25. package/dist/cli/index.js.map +1 -1
  26. package/dist/components/HelpScreen.js +1 -2
  27. package/dist/components/HelpScreen.js.map +1 -1
  28. package/dist/components/OverlayPanel.d.ts +4 -1
  29. package/dist/components/OverlayPanel.js +5 -3
  30. package/dist/components/OverlayPanel.js.map +1 -1
  31. package/dist/components/WorkItemList.js +62 -51
  32. package/dist/components/WorkItemList.js.map +1 -1
  33. package/dist/stores/backendDataStore.js +28 -12
  34. package/dist/stores/backendDataStore.js.map +1 -1
  35. package/dist/stores/uiStore.d.ts +1 -3
  36. package/dist/stores/uiStore.js.map +1 -1
  37. package/package.json +1 -1
  38. package/dist/backends/gitlab/glab.d.ts +0 -6
  39. package/dist/backends/gitlab/glab.js +0 -43
  40. package/dist/backends/gitlab/glab.js.map +0 -1
  41. package/dist/backends/gitlab/group.d.ts +0 -1
  42. package/dist/backends/gitlab/group.js +0 -33
  43. package/dist/backends/gitlab/group.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tic",
3
3
  "description": "Issue tracking skills for Claude Code",
4
- "version": "3.0.0",
4
+ "version": "4.0.0",
5
5
  "author": {
6
6
  "name": "Sascha Krug"
7
7
  },
@@ -0,0 +1,37 @@
1
+ export declare const GITLAB_ACCOUNT = "gitlab.com";
2
+ export declare const GITLAB_PAT_ACCOUNT = "gitlab.com:pat";
3
+ export declare const DEFAULT_GITLAB_CLIENT_ID = "cdcaceeece0df785f6df0e8b94fce6669ec8521787844faed02a5605b29e05bd";
4
+ /**
5
+ * Retrieve the stored GitLab OAuth token from the system keychain.
6
+ * Returns null if no token is found.
7
+ */
8
+ export declare function getGitLabToken(): string | null;
9
+ /**
10
+ * Retrieve the stored GitLab PAT from the system keychain.
11
+ * Returns null if no PAT is found.
12
+ */
13
+ export declare function getGitLabPat(): string | null;
14
+ /**
15
+ * Store a GitLab PAT in the system keychain.
16
+ */
17
+ export declare function setGitLabPat(pat: string): void;
18
+ /**
19
+ * Remove all stored GitLab tokens (OAuth and PAT) from the system keychain.
20
+ */
21
+ export declare function clearGitLabTokens(): void;
22
+ export interface AuthenticateGitLabOptions {
23
+ clientId?: string;
24
+ onCode?: (userCode: string, verificationUri: string) => void;
25
+ }
26
+ /**
27
+ * Run the GitLab OAuth device flow to authenticate the user.
28
+ *
29
+ * 1. Requests a device code from GitLab
30
+ * 2. Calls onCode callback so the caller can display the code/URL to the user
31
+ * 3. Polls GitLab for the access token at the specified interval
32
+ * 4. Stores the token in the system keychain on success
33
+ *
34
+ * @returns The access token
35
+ * @throws On access_denied, expired_token, or unexpected errors
36
+ */
37
+ export declare function authenticateGitLab(options?: AuthenticateGitLabOptions): Promise<string>;
@@ -0,0 +1,111 @@
1
+ import { getToken, setToken, deleteToken } from './keychain.js';
2
+ export const GITLAB_ACCOUNT = 'gitlab.com';
3
+ export const GITLAB_PAT_ACCOUNT = 'gitlab.com:pat';
4
+ export const DEFAULT_GITLAB_CLIENT_ID = 'cdcaceeece0df785f6df0e8b94fce6669ec8521787844faed02a5605b29e05bd';
5
+ /**
6
+ * Retrieve the stored GitLab OAuth token from the system keychain.
7
+ * Returns null if no token is found.
8
+ */
9
+ export function getGitLabToken() {
10
+ return getToken(GITLAB_ACCOUNT);
11
+ }
12
+ /**
13
+ * Retrieve the stored GitLab PAT from the system keychain.
14
+ * Returns null if no PAT is found.
15
+ */
16
+ export function getGitLabPat() {
17
+ return getToken(GITLAB_PAT_ACCOUNT);
18
+ }
19
+ /**
20
+ * Store a GitLab PAT in the system keychain.
21
+ */
22
+ export function setGitLabPat(pat) {
23
+ setToken(GITLAB_PAT_ACCOUNT, pat);
24
+ }
25
+ /**
26
+ * Remove all stored GitLab tokens (OAuth and PAT) from the system keychain.
27
+ */
28
+ export function clearGitLabTokens() {
29
+ deleteToken(GITLAB_ACCOUNT);
30
+ deleteToken(GITLAB_PAT_ACCOUNT);
31
+ }
32
+ function isTokenError(response) {
33
+ return 'error' in response;
34
+ }
35
+ function sleep(ms) {
36
+ return new Promise((resolve) => setTimeout(resolve, ms));
37
+ }
38
+ /**
39
+ * Run the GitLab OAuth device flow to authenticate the user.
40
+ *
41
+ * 1. Requests a device code from GitLab
42
+ * 2. Calls onCode callback so the caller can display the code/URL to the user
43
+ * 3. Polls GitLab for the access token at the specified interval
44
+ * 4. Stores the token in the system keychain on success
45
+ *
46
+ * @returns The access token
47
+ * @throws On access_denied, expired_token, or unexpected errors
48
+ */
49
+ export async function authenticateGitLab(options) {
50
+ const clientId = options?.clientId ?? DEFAULT_GITLAB_CLIENT_ID;
51
+ // Step 1: Request device code
52
+ const codeResponse = await fetch('https://gitlab.com/oauth/authorize_device', {
53
+ method: 'POST',
54
+ headers: {
55
+ Accept: 'application/json',
56
+ 'Content-Type': 'application/json',
57
+ },
58
+ body: JSON.stringify({
59
+ client_id: clientId,
60
+ scope: 'api',
61
+ }),
62
+ });
63
+ if (!codeResponse.ok) {
64
+ throw new Error(`Failed to request device code: ${codeResponse.status} ${codeResponse.statusText}`);
65
+ }
66
+ const deviceCode = (await codeResponse.json());
67
+ // Step 2: Notify caller with user code and verification URL
68
+ options?.onCode?.(deviceCode.user_code, deviceCode.verification_uri);
69
+ // Step 3: Poll for access token
70
+ let interval = deviceCode.interval * 1000; // Convert to ms
71
+ while (true) {
72
+ await sleep(interval);
73
+ const tokenResponse = await fetch('https://gitlab.com/oauth/token', {
74
+ method: 'POST',
75
+ headers: {
76
+ Accept: 'application/json',
77
+ 'Content-Type': 'application/json',
78
+ },
79
+ body: JSON.stringify({
80
+ client_id: clientId,
81
+ device_code: deviceCode.device_code,
82
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
83
+ }),
84
+ });
85
+ if (!tokenResponse.ok) {
86
+ throw new Error(`Failed to poll for token: ${tokenResponse.status} ${tokenResponse.statusText}`);
87
+ }
88
+ const data = (await tokenResponse.json());
89
+ if (isTokenError(data)) {
90
+ switch (data.error) {
91
+ case 'authorization_pending':
92
+ // User hasn't authorized yet, keep polling
93
+ continue;
94
+ case 'slow_down':
95
+ // GitLab wants us to increase the polling interval by 5 seconds
96
+ interval += 5000;
97
+ continue;
98
+ case 'access_denied':
99
+ throw new Error('Authorization was denied by the user');
100
+ case 'expired_token':
101
+ throw new Error('Device code has expired. Please restart the authentication flow.');
102
+ default:
103
+ throw new Error(`Authentication failed: ${data.error}${data.error_description ? ` - ${data.error_description}` : ''}`);
104
+ }
105
+ }
106
+ // Success - store token and return
107
+ setToken(GITLAB_ACCOUNT, data.access_token);
108
+ return data.access_token;
109
+ }
110
+ }
111
+ //# sourceMappingURL=gitlab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitlab.js","sourceRoot":"","sources":["../../src/auth/gitlab.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,7 @@ export const BACKEND_CLI = {
6
6
  none: null,
7
7
  filesystem: null,
8
8
  github: 'gh',
9
- gitlab: 'glab',
9
+ gitlab: null,
10
10
  azure: 'az',
11
11
  jira: null,
12
12
  };
@@ -1 +1 @@
1
- {"version":3,"file":"availability.js","sourceRoot":"","sources":["../../src/backends/availability.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAuC;IAC7D,IAAI,EAAE,IAAI;IACV,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,MAAM;IACd,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;CACX,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,OAAoB;IAEpB,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,QAAQ,CACpB,MAAM,EACN,CAAC,WAAW,CAAC,EACb,EAAE,OAAO,EAAE,IAAI,EAAE,EACjB,CAAC,KAAK,EAAE,EAAE;YACR,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC,CACF,CAAC;QACF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B;IAG/C,MAAM,QAAQ,GAAkB;QAC9B,MAAM;QACN,YAAY;QACZ,QAAQ;QACR,QAAQ;QACR,OAAO;QACP,MAAM;KACP,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,wBAAwB,CAAC,CAAC,CAAC,CAAU,CAAC,CAC3E,CAAC;IACF,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,CAAiC,CAAC;AACrE,CAAC"}
1
+ {"version":3,"file":"availability.js","sourceRoot":"","sources":["../../src/backends/availability.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAuC;IAC7D,IAAI,EAAE,IAAI;IACV,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;CACX,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,OAAoB;IAEpB,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,QAAQ,CACpB,MAAM,EACN,CAAC,WAAW,CAAC,EACb,EAAE,OAAO,EAAE,IAAI,EAAE,EACjB,CAAC,KAAK,EAAE,EAAE;YACR,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC,CACF,CAAC;QACF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B;IAG/C,MAAM,QAAQ,GAAkB;QAC9B,MAAM;QACN,YAAY;QACZ,QAAQ;QACR,QAAQ;QACR,OAAO;QACP,MAAM;KACP,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,wBAAwB,CAAC,CAAC,CAAC,CAAU,CAAC,CAC3E,CAAC;IACF,OAAO,MAAM,CAAC,WAAW,CAAC,OAAO,CAAiC,CAAC;AACrE,CAAC"}
@@ -54,7 +54,7 @@ export async function createRemoteBackend(root, backendType, options) {
54
54
  }
55
55
  case 'gitlab': {
56
56
  const { GitLabBackend } = await import('./gitlab/index.js');
57
- return new GitLabBackend(root);
57
+ return GitLabBackend.create(root, options);
58
58
  }
59
59
  case 'azure': {
60
60
  const { AzureDevOpsBackend } = await import('./ado/index.js');
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/backends/factory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/backends/factory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { BaseApiClient } from '../shared/api-client.js';
2
+ export interface Connection<T> {
3
+ nodes: T[];
4
+ pageInfo: {
5
+ hasNextPage: boolean;
6
+ endCursor: string | null;
7
+ };
8
+ }
9
+ export declare class GitLabApiClient extends BaseApiClient {
10
+ constructor(token: string);
11
+ graphql<T>(query: string, variables?: Record<string, unknown>): Promise<T>;
12
+ private graphqlFetch;
13
+ paginate<T>(query: string, variables?: Record<string, unknown>, extractConnection?: (data: unknown) => Connection<T>): AsyncGenerator<T[]>;
14
+ }
@@ -0,0 +1,53 @@
1
+ import { AuthError, BaseApiClient } from '../shared/api-client.js';
2
+ export class GitLabApiClient extends BaseApiClient {
3
+ constructor(token) {
4
+ super(token, 'https://gitlab.com');
5
+ }
6
+ async graphql(query, variables) {
7
+ return this.retry(() => this.graphqlFetch(query, variables));
8
+ }
9
+ async graphqlFetch(query, variables) {
10
+ const url = this.baseUrl + '/api/graphql';
11
+ const headers = {
12
+ Authorization: `Bearer ${this.token}`,
13
+ 'Content-Type': 'application/json',
14
+ };
15
+ const response = await globalThis.fetch(url, {
16
+ method: 'POST',
17
+ headers,
18
+ body: JSON.stringify({ query, variables }),
19
+ });
20
+ this.checkRateLimit(response.headers);
21
+ if (response.status === 401) {
22
+ throw new AuthError();
23
+ }
24
+ if (!response.ok) {
25
+ const text = await response.text();
26
+ throw new Error(`HTTP ${response.status}: ${text}`);
27
+ }
28
+ const json = (await response.json());
29
+ const firstError = json.errors?.[0];
30
+ if (firstError) {
31
+ throw new Error(`GraphQL error: ${firstError.message}`);
32
+ }
33
+ return json.data;
34
+ }
35
+ async *paginate(query, variables, extractConnection) {
36
+ if (!extractConnection) {
37
+ throw new Error('GitLabApiClient.paginate requires variables and extractConnection arguments');
38
+ }
39
+ let cursor = null;
40
+ let hasNextPage = true;
41
+ while (hasNextPage) {
42
+ const data = await this.graphql(query, {
43
+ ...variables,
44
+ cursor,
45
+ });
46
+ const connection = extractConnection(data);
47
+ yield connection.nodes;
48
+ hasNextPage = connection.pageInfo.hasNextPage;
49
+ cursor = connection.pageInfo.endCursor;
50
+ }
51
+ }
52
+ }
53
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/backends/gitlab/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAUnE,MAAM,OAAO,eAAgB,SAAQ,aAAa;IAChD,YAAY,KAAa;QACvB,KAAK,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,OAAO,CACX,KAAa,EACb,SAAmC;QAEnC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAI,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAClE,CAAC;IAEO,KAAK,CAAC,YAAY,CACxB,KAAa,EACb,SAAmC;QAEnC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,cAAc,CAAC;QAE1C,MAAM,OAAO,GAA2B;YACtC,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;YACrC,cAAc,EAAE,kBAAkB;SACnC,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE;YAC3C,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;SAC3C,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAEtC,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,SAAS,EAAE,CAAC;QACxB,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAGlC,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,kBAAkB,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,IAAI,CAAC,IAAS,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,CAAC,QAAQ,CACb,KAAa,EACb,SAAmC,EACnC,iBAAoD;QAEpD,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,6EAA6E,CAC9E,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,GAAkB,IAAI,CAAC;QACjC,IAAI,WAAW,GAAG,IAAI,CAAC;QAEvB,OAAO,WAAW,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAU,KAAK,EAAE;gBAC9C,GAAG,SAAS;gBACZ,MAAM;aACP,CAAC,CAAC;YAEH,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAC3C,MAAM,UAAU,CAAC,KAAK,CAAC;YAEvB,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC;YAC9C,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC;QACzC,CAAC;IACH,CAAC;CACF"}
@@ -1,13 +1,18 @@
1
1
  import { BaseBackend } from '../types.js';
2
2
  import type { BackendCapabilities } from '../types.js';
3
3
  import type { WorkItem, NewWorkItem, NewComment, Comment, Template } from '../../types.js';
4
+ export interface GitLabBackendOptions {
5
+ skipAuth?: boolean;
6
+ }
4
7
  export declare class GitLabBackend extends BaseBackend {
8
+ private api;
9
+ private remote;
10
+ private typeIds;
11
+ private gidCache;
5
12
  private cwd;
6
- private group;
7
- private cachedIterations;
8
- /** Maps template slug → original GitLab filename (without .md) */
9
- private templateNameCache;
10
- constructor(cwd: string);
13
+ private cachedMilestones;
14
+ private constructor();
15
+ static create(cwd: string, options?: GitLabBackendOptions): Promise<GitLabBackend>;
11
16
  protected onCacheInvalidate(): void;
12
17
  getCapabilities(): BackendCapabilities;
13
18
  getStatuses(): Promise<string[]>;
@@ -28,16 +33,13 @@ export declare class GitLabBackend extends BaseBackend {
28
33
  getItemUrl(id: string): string;
29
34
  openItem(id: string): Promise<void>;
30
35
  listTemplates(): Promise<Template[]>;
31
- /** Resolve a slug to the original GitLab filename (without .md). Falls back to slug. */
32
- private resolveTemplateName;
33
36
  getTemplate(slug: string): Promise<Template>;
34
37
  createTemplate(template: Template): Promise<Template>;
35
38
  updateTemplate(oldSlug: string, template: Template): Promise<Template>;
36
39
  deleteTemplate(slug: string): Promise<void>;
37
- private fetchIterations;
38
- private ensureLabels;
39
- private createIssue;
40
- private createEpic;
41
- private updateIssue;
42
- private updateEpic;
40
+ private cacheGid;
41
+ private resolveGid;
42
+ private buildWidgetUpdates;
43
+ private applyUpdate;
44
+ private fetchMilestones;
43
45
  }