@chemx/starter-kit 26.9.9-786 → 26.9.11-481
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/cli/audit/ast-visitors.js +243 -0
- package/cli/audit/discussion-store.js +39 -0
- package/cli/audit/history.d.ts +69 -0
- package/cli/audit/history.js +397 -0
- package/cli/audit/metrics.js +179 -0
- package/cli/audit/prompts.js +174 -0
- package/cli/audit/reporter-ascii.d.ts +4 -0
- package/cli/audit/reporter-ascii.js +99 -0
- package/cli/audit/reporter-grades.js +275 -0
- package/cli/audit/reporter-markdown.js +137 -0
- package/cli/audit/reporter-utils.js +125 -0
- package/cli/audit/reporter.js +497 -0
- package/cli/audit/rules-helpers.js +109 -0
- package/cli/audit/rules-registry.js +97 -0
- package/cli/audit/rules.js +123 -0
- package/cli/audit/social-constants.js +4 -0
- package/cli/audit/social-gh.js +126 -0
- package/cli/audit/social-git.js +214 -0
- package/cli/audit/social-http.js +222 -0
- package/cli/audit/social-publisher.js +193 -0
- package/cli/audit/social.d.ts +69 -0
- package/cli/audit/social.js +303 -0
- package/cli/audit/types.d.ts +140 -0
- package/cli/audit.d.ts +3 -24
- package/cli/audit.js +207 -210
- package/cli/help.d.ts +1 -0
- package/cli/help.js +136 -0
- package/cli/index.js +128 -566
- package/cli/installer-templates.js +91 -0
- package/cli/installer.d.ts +21 -0
- package/cli/installer.js +104 -0
- package/cli/license.js +320 -0
- package/cli/navigator-actions.js +274 -0
- package/cli/navigator-banner.js +98 -0
- package/cli/navigator-conversion.js +100 -0
- package/cli/navigator-grades.js +87 -0
- package/cli/navigator-menu.js +127 -0
- package/cli/navigator-paged.js +86 -0
- package/cli/navigator-share.js +129 -0
- package/cli/navigator.d.ts +43 -0
- package/cli/navigator.js +126 -0
- package/cli/scaffold.js +148 -0
- package/cli/terminal.js +126 -0
- package/docs/CHANGELOG.md +101 -0
- package/package.json +11 -10
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DISCUSSION_CATEGORY,
|
|
3
|
+
DISCUSSION_CATEGORY_SLUG
|
|
4
|
+
} from './social-constants.js';
|
|
5
|
+
|
|
6
|
+
export const findMatchedCategory = (categories, categoryName) => {
|
|
7
|
+
const exactName = categories.find((c) => c.name === categoryName);
|
|
8
|
+
if (exactName) return exactName;
|
|
9
|
+
|
|
10
|
+
const exactSlug = categories.find((c) => c.slug === categoryName);
|
|
11
|
+
if (exactSlug) return exactSlug;
|
|
12
|
+
|
|
13
|
+
const defaultSlug = categories.find((c) => c.slug === DISCUSSION_CATEGORY_SLUG);
|
|
14
|
+
if (defaultSlug) return defaultSlug;
|
|
15
|
+
|
|
16
|
+
const targetLower = categoryName.toLowerCase();
|
|
17
|
+
const lowerName = categories.find((c) => c.name.toLowerCase() === targetLower);
|
|
18
|
+
if (lowerName) return lowerName;
|
|
19
|
+
|
|
20
|
+
const lowerSlug = categories.find((c) => c.slug.toLowerCase() === targetLower);
|
|
21
|
+
if (lowerSlug) return lowerSlug;
|
|
22
|
+
|
|
23
|
+
const chemxName = categories.find((c) => c.name.toLowerCase().includes('chemx'));
|
|
24
|
+
if (chemxName) return chemxName;
|
|
25
|
+
|
|
26
|
+
const chemxSlug = categories.find((c) => c.slug.toLowerCase().includes('chemx'));
|
|
27
|
+
if (chemxSlug) return chemxSlug;
|
|
28
|
+
|
|
29
|
+
const auditName = categories.find((c) => c.name.toLowerCase().includes('audit'));
|
|
30
|
+
if (auditName) return auditName;
|
|
31
|
+
|
|
32
|
+
const auditSlug = categories.find((c) => c.slug.toLowerCase().includes('audit'));
|
|
33
|
+
if (auditSlug) return auditSlug;
|
|
34
|
+
|
|
35
|
+
const generalName = categories.find((c) => c.name.toLowerCase().includes('general'));
|
|
36
|
+
if (generalName) return generalName;
|
|
37
|
+
|
|
38
|
+
return categories[0];
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const publishDiscussionViaHttp = async (token, repo, title, body, categoryName = DISCUSSION_CATEGORY) => {
|
|
42
|
+
if (!token) return { success: false, url: null, id: null, number: null, error: 'No GitHub token provided' };
|
|
43
|
+
|
|
44
|
+
const [owner, name] = repo.split('/');
|
|
45
|
+
if (!owner || !name) return { success: false, url: null, id: null, number: null, error: `Invalid repository format: ${repo}` };
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const metaQuery = `
|
|
49
|
+
query($owner: String!, $name: String!) {
|
|
50
|
+
repository(owner: $owner, name: $name) {
|
|
51
|
+
id
|
|
52
|
+
discussionCategories(first: 25) {
|
|
53
|
+
nodes {
|
|
54
|
+
id
|
|
55
|
+
name
|
|
56
|
+
slug
|
|
57
|
+
emoji
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
`;
|
|
63
|
+
|
|
64
|
+
const metaRes = await fetch('https://api.github.com/graphql', {
|
|
65
|
+
method: 'POST',
|
|
66
|
+
headers: {
|
|
67
|
+
'Authorization': `Bearer ${token}`,
|
|
68
|
+
'Content-Type': 'application/json',
|
|
69
|
+
'User-Agent': 'Chemical-X-Audit-CLI'
|
|
70
|
+
},
|
|
71
|
+
body: JSON.stringify({ query: metaQuery, variables: { owner, name } })
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const metaJson = await metaRes.json();
|
|
75
|
+
if (metaJson.errors) {
|
|
76
|
+
return { success: false, url: null, id: null, number: null, error: metaJson.errors[0]?.message || 'GraphQL error fetching categories' };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const repositoryId = metaJson.data?.repository?.id;
|
|
80
|
+
const categories = metaJson.data?.repository?.discussionCategories?.nodes || [];
|
|
81
|
+
|
|
82
|
+
if (!repositoryId || categories.length === 0) {
|
|
83
|
+
return { success: false, url: null, id: null, number: null, error: `Repository ${repo} has no discussions enabled` };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const matchedCat = findMatchedCategory(categories, categoryName);
|
|
87
|
+
|
|
88
|
+
const mutation = `
|
|
89
|
+
mutation($repositoryId: ID!, $categoryId: ID!, $title: String!, $body: String!) {
|
|
90
|
+
createDiscussion(input: { repositoryId: $repositoryId, categoryId: $categoryId, title: $title, body: $body }) {
|
|
91
|
+
discussion {
|
|
92
|
+
id
|
|
93
|
+
number
|
|
94
|
+
url
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
`;
|
|
99
|
+
|
|
100
|
+
const postRes = await fetch('https://api.github.com/graphql', {
|
|
101
|
+
method: 'POST',
|
|
102
|
+
headers: {
|
|
103
|
+
'Authorization': `Bearer ${token}`,
|
|
104
|
+
'Content-Type': 'application/json',
|
|
105
|
+
'User-Agent': 'Chemical-X-Audit-CLI'
|
|
106
|
+
},
|
|
107
|
+
body: JSON.stringify({
|
|
108
|
+
query: mutation,
|
|
109
|
+
variables: { repositoryId, categoryId: matchedCat.id, title, body }
|
|
110
|
+
})
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const postJson = await postRes.json();
|
|
114
|
+
if (postJson.errors) {
|
|
115
|
+
return { success: false, url: null, id: null, number: null, error: postJson.errors[0]?.message || 'Failed creating discussion' };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const disc = postJson.data?.createDiscussion?.discussion;
|
|
119
|
+
const url = disc?.url;
|
|
120
|
+
return {
|
|
121
|
+
success: Boolean(url),
|
|
122
|
+
url: url || null,
|
|
123
|
+
id: disc?.id || null,
|
|
124
|
+
number: disc?.number || null,
|
|
125
|
+
error: null
|
|
126
|
+
};
|
|
127
|
+
} catch (err) {
|
|
128
|
+
return { success: false, url: null, id: null, number: null, error: err.message };
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export const viewDiscussionViaHttp = async (token, repo, discussionNumber) => {
|
|
133
|
+
const [owner, name] = repo.split('/');
|
|
134
|
+
if (!owner || !name) return null;
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
const query = `
|
|
138
|
+
query($owner: String!, $name: String!, $number: Int!) {
|
|
139
|
+
repository(owner: $owner, name: $name) {
|
|
140
|
+
discussion(number: $number) {
|
|
141
|
+
id
|
|
142
|
+
number
|
|
143
|
+
title
|
|
144
|
+
body
|
|
145
|
+
url
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
`;
|
|
150
|
+
const res = await fetch('https://api.github.com/graphql', {
|
|
151
|
+
method: 'POST',
|
|
152
|
+
headers: {
|
|
153
|
+
'Authorization': `Bearer ${token}`,
|
|
154
|
+
'Content-Type': 'application/json',
|
|
155
|
+
'User-Agent': 'Chemical-X-Audit-CLI'
|
|
156
|
+
},
|
|
157
|
+
body: JSON.stringify({ query, variables: { owner, name, number: Number(discussionNumber) } })
|
|
158
|
+
});
|
|
159
|
+
const json = await res.json();
|
|
160
|
+
return json.data?.repository?.discussion || null;
|
|
161
|
+
} catch {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export const postDiscussionCommentViaHttp = async (token, discussionId, commentBody) => {
|
|
167
|
+
try {
|
|
168
|
+
const mutation = `
|
|
169
|
+
mutation($discussionId: ID!, $body: String!) {
|
|
170
|
+
addDiscussionComment(input: { discussionId: $discussionId, body: $body }) {
|
|
171
|
+
comment {
|
|
172
|
+
id
|
|
173
|
+
url
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
`;
|
|
178
|
+
const res = await fetch('https://api.github.com/graphql', {
|
|
179
|
+
method: 'POST',
|
|
180
|
+
headers: {
|
|
181
|
+
'Authorization': `Bearer ${token}`,
|
|
182
|
+
'Content-Type': 'application/json',
|
|
183
|
+
'User-Agent': 'Chemical-X-Audit-CLI'
|
|
184
|
+
},
|
|
185
|
+
body: JSON.stringify({ query: mutation, variables: { discussionId, body: commentBody } })
|
|
186
|
+
});
|
|
187
|
+
const json = await res.json();
|
|
188
|
+
return Boolean(json.data?.addDiscussionComment?.comment?.id);
|
|
189
|
+
} catch {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
export const editDiscussionViaHttp = async (token, discussionId, title, body) => {
|
|
195
|
+
try {
|
|
196
|
+
const mutation = `
|
|
197
|
+
mutation($discussionId: ID!, $title: String!, $body: String!) {
|
|
198
|
+
updateDiscussion(input: { discussionId: $discussionId, title: $title, body: $body }) {
|
|
199
|
+
discussion {
|
|
200
|
+
id
|
|
201
|
+
number
|
|
202
|
+
url
|
|
203
|
+
title
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
`;
|
|
208
|
+
const res = await fetch('https://api.github.com/graphql', {
|
|
209
|
+
method: 'POST',
|
|
210
|
+
headers: {
|
|
211
|
+
'Authorization': `Bearer ${token}`,
|
|
212
|
+
'Content-Type': 'application/json',
|
|
213
|
+
'User-Agent': 'Chemical-X-Audit-CLI'
|
|
214
|
+
},
|
|
215
|
+
body: JSON.stringify({ query: mutation, variables: { discussionId, title, body } })
|
|
216
|
+
});
|
|
217
|
+
const json = await res.json();
|
|
218
|
+
return Boolean(json.data?.updateDiscussion?.discussion?.id);
|
|
219
|
+
} catch {
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
};
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DISCUSSION_CATEGORY,
|
|
3
|
+
DISCUSSION_CATEGORY_SLUG,
|
|
4
|
+
ORG_DISCUSSIONS_URL,
|
|
5
|
+
DEFAULT_DISCUSSION_REPO
|
|
6
|
+
} from './social-constants.js';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
getStoredDiscussion,
|
|
10
|
+
saveStoredDiscussion,
|
|
11
|
+
clearStoredDiscussion
|
|
12
|
+
} from './discussion-store.js';
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
findMatchedCategory,
|
|
16
|
+
publishDiscussionViaHttp,
|
|
17
|
+
viewDiscussionViaHttp,
|
|
18
|
+
postDiscussionCommentViaHttp,
|
|
19
|
+
editDiscussionViaHttp
|
|
20
|
+
} from './social-http.js';
|
|
21
|
+
|
|
22
|
+
import {
|
|
23
|
+
publishDiscussionViaGh,
|
|
24
|
+
viewDiscussionViaGh,
|
|
25
|
+
postDiscussionCommentViaGh,
|
|
26
|
+
editDiscussionViaGh,
|
|
27
|
+
findExistingDiscussionViaGh
|
|
28
|
+
} from './social-gh.js';
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
DISCUSSION_CATEGORY,
|
|
32
|
+
DISCUSSION_CATEGORY_SLUG,
|
|
33
|
+
ORG_DISCUSSIONS_URL,
|
|
34
|
+
DEFAULT_DISCUSSION_REPO
|
|
35
|
+
} from './social-constants.js';
|
|
36
|
+
|
|
37
|
+
export {
|
|
38
|
+
getStoredDiscussion,
|
|
39
|
+
saveStoredDiscussion,
|
|
40
|
+
clearStoredDiscussion
|
|
41
|
+
} from './discussion-store.js';
|
|
42
|
+
|
|
43
|
+
export {
|
|
44
|
+
findMatchedCategory,
|
|
45
|
+
publishDiscussionViaHttp,
|
|
46
|
+
viewDiscussionViaHttp,
|
|
47
|
+
postDiscussionCommentViaHttp,
|
|
48
|
+
editDiscussionViaHttp
|
|
49
|
+
} from './social-http.js';
|
|
50
|
+
|
|
51
|
+
export {
|
|
52
|
+
publishDiscussionViaGh,
|
|
53
|
+
viewDiscussionViaGh,
|
|
54
|
+
postDiscussionCommentViaGh,
|
|
55
|
+
editDiscussionViaGh,
|
|
56
|
+
findExistingDiscussionViaGh
|
|
57
|
+
} from './social-gh.js';
|
|
58
|
+
|
|
59
|
+
export const formatArchiveComment = (previousTitle, previousBody) => {
|
|
60
|
+
const archiveTimestamp = new Date().toUTCString();
|
|
61
|
+
return [
|
|
62
|
+
'## 📜 Previous Audit Snapshot (Archived)',
|
|
63
|
+
'',
|
|
64
|
+
`> **Archived on:** ${archiveTimestamp}`,
|
|
65
|
+
`> **Previous Status:** ${previousTitle || 'Prior Report'}`,
|
|
66
|
+
'',
|
|
67
|
+
'---',
|
|
68
|
+
'',
|
|
69
|
+
previousBody
|
|
70
|
+
].join('\n');
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const publishDiscussion = async (repo, title, body, category = DISCUSSION_CATEGORY) => {
|
|
74
|
+
const envToken = process.env.GH_TOKEN || process.env.GITHUB_TOKEN;
|
|
75
|
+
if (envToken) {
|
|
76
|
+
const httpResult = await publishDiscussionViaHttp(envToken, repo, title, body, category);
|
|
77
|
+
if (httpResult.success) {
|
|
78
|
+
return httpResult;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return publishDiscussionViaGh(repo, title, body, category);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const publishOrUpdateDiscussion = async (
|
|
86
|
+
repo = DEFAULT_DISCUSSION_REPO,
|
|
87
|
+
title,
|
|
88
|
+
body,
|
|
89
|
+
category = DISCUSSION_CATEGORY,
|
|
90
|
+
options = {}
|
|
91
|
+
) => {
|
|
92
|
+
const envToken = process.env.GH_TOKEN || process.env.GITHUB_TOKEN;
|
|
93
|
+
const stored = getStoredDiscussion();
|
|
94
|
+
const targetRepo = repo || DEFAULT_DISCUSSION_REPO;
|
|
95
|
+
|
|
96
|
+
let existingDiscussion = null;
|
|
97
|
+
|
|
98
|
+
if (stored && stored.number && (!stored.repo || stored.repo === targetRepo)) {
|
|
99
|
+
if (envToken) {
|
|
100
|
+
existingDiscussion = await viewDiscussionViaHttp(envToken, targetRepo, stored.number);
|
|
101
|
+
}
|
|
102
|
+
if (!existingDiscussion) {
|
|
103
|
+
existingDiscussion = viewDiscussionViaGh(targetRepo, stored.number);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (!existingDiscussion && options.projectName) {
|
|
108
|
+
existingDiscussion = findExistingDiscussionViaGh(targetRepo, options.projectName);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (existingDiscussion && existingDiscussion.number) {
|
|
112
|
+
const discussionNumber = existingDiscussion.number;
|
|
113
|
+
const discussionId = existingDiscussion.id || stored?.discussionId;
|
|
114
|
+
const previousBody = existingDiscussion.body || '';
|
|
115
|
+
|
|
116
|
+
const hasPreviousBody = previousBody.trim().length > 0;
|
|
117
|
+
if (hasPreviousBody) {
|
|
118
|
+
const archiveComment = formatArchiveComment(existingDiscussion.title, previousBody);
|
|
119
|
+
|
|
120
|
+
if (envToken && discussionId) {
|
|
121
|
+
await postDiscussionCommentViaHttp(envToken, discussionId, archiveComment);
|
|
122
|
+
} else {
|
|
123
|
+
postDiscussionCommentViaGh(targetRepo, discussionNumber, archiveComment);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
let editSuccess = false;
|
|
128
|
+
if (envToken && discussionId) {
|
|
129
|
+
editSuccess = await editDiscussionViaHttp(envToken, discussionId, title, body);
|
|
130
|
+
}
|
|
131
|
+
if (!editSuccess) {
|
|
132
|
+
editSuccess = editDiscussionViaGh(targetRepo, discussionNumber, title, body);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const fallbackUrl = `https://github.com/${targetRepo}/discussions/${discussionNumber}`;
|
|
136
|
+
const discussionUrl = existingDiscussion.url || stored?.url || fallbackUrl;
|
|
137
|
+
|
|
138
|
+
if (editSuccess) {
|
|
139
|
+
saveStoredDiscussion({
|
|
140
|
+
repo: targetRepo,
|
|
141
|
+
number: discussionNumber,
|
|
142
|
+
discussionId,
|
|
143
|
+
url: discussionUrl,
|
|
144
|
+
projectName: options.projectName || stored?.projectName || '',
|
|
145
|
+
website: options.website || stored?.website || '',
|
|
146
|
+
title,
|
|
147
|
+
lastPublishedAt: new Date().toISOString()
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
success: true,
|
|
152
|
+
url: discussionUrl,
|
|
153
|
+
updated: true,
|
|
154
|
+
discussionNumber,
|
|
155
|
+
error: null
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const pubResult = await publishDiscussion(targetRepo, title, body, category);
|
|
161
|
+
if (pubResult.success && pubResult.url) {
|
|
162
|
+
const match = pubResult.url.match(/\/discussions\/(\d+)/);
|
|
163
|
+
const parsedNumber = match ? parseInt(match[1], 10) : null;
|
|
164
|
+
const discussionNumber = pubResult.number || parsedNumber;
|
|
165
|
+
|
|
166
|
+
saveStoredDiscussion({
|
|
167
|
+
repo: targetRepo,
|
|
168
|
+
number: discussionNumber,
|
|
169
|
+
discussionId: pubResult.id || null,
|
|
170
|
+
url: pubResult.url,
|
|
171
|
+
projectName: options.projectName || '',
|
|
172
|
+
website: options.website || '',
|
|
173
|
+
title,
|
|
174
|
+
lastPublishedAt: new Date().toISOString()
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
success: true,
|
|
179
|
+
url: pubResult.url,
|
|
180
|
+
updated: false,
|
|
181
|
+
discussionNumber,
|
|
182
|
+
error: null
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return {
|
|
187
|
+
success: false,
|
|
188
|
+
url: null,
|
|
189
|
+
updated: false,
|
|
190
|
+
discussionNumber: null,
|
|
191
|
+
error: pubResult.error
|
|
192
|
+
};
|
|
193
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { AuditReport } from './types';
|
|
2
|
+
import type { AuditSnapshot } from './history';
|
|
3
|
+
|
|
4
|
+
export interface DiscussionContent {
|
|
5
|
+
readonly title: string;
|
|
6
|
+
readonly category: string;
|
|
7
|
+
readonly categorySlug: string;
|
|
8
|
+
readonly body: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface GitRepoInfo {
|
|
12
|
+
readonly owner: string;
|
|
13
|
+
readonly repo: string;
|
|
14
|
+
readonly nameWithOwner: string;
|
|
15
|
+
readonly url: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export declare const DISCUSSION_CATEGORY: string;
|
|
19
|
+
export declare const DISCUSSION_CATEGORY_SLUG: string;
|
|
20
|
+
export declare const ORG_DISCUSSIONS_URL: string;
|
|
21
|
+
export declare const DEFAULT_DISCUSSION_REPO: string;
|
|
22
|
+
|
|
23
|
+
export declare function parseGitRemoteUrl(url: string): GitRepoInfo | null;
|
|
24
|
+
export declare function detectGitRepoInfo(cwd?: string): GitRepoInfo;
|
|
25
|
+
export declare function detectGitHubUser(preferredUser?: string): string;
|
|
26
|
+
export declare function copyToClipboard(text: string): boolean;
|
|
27
|
+
export declare function resolveBadgeColor(score: number): string;
|
|
28
|
+
export declare function resolveHotspotTierText(lineCount: number): string;
|
|
29
|
+
export declare function resolvePillarProgressionBadge(isImproved: boolean, beforeStatus: string, afterStatus: string): string;
|
|
30
|
+
export declare function formatWebUrl(url: string): string;
|
|
31
|
+
export declare function resolveExcessCostPerPass(tokensObj?: any, fallbackCostPerMillion?: number): number;
|
|
32
|
+
export declare function resolveMonthlyWastePerDev(tokensObj?: any, fallbackCostPerMillion?: number): number;
|
|
33
|
+
export declare function resolveWeeklyWastePerDev(tokensObj?: any, fallbackCostPerMillion?: number): number;
|
|
34
|
+
export declare function generateDiscussionContent(report: AuditReport, username: string, projectName?: string, repoUrl?: string, liveUrl?: string): DiscussionContent;
|
|
35
|
+
export declare function generateTransformationDiscussionContent(beforeSnapshot: AuditSnapshot, afterSnapshot: AuditSnapshot, username: string, projectName?: string, repoUrl?: string, liveUrl?: string): DiscussionContent;
|
|
36
|
+
export declare function publishDiscussionViaGh(repo: string, title: string, body: string, category?: string): { success: boolean; url: string | null; error?: string | null };
|
|
37
|
+
export declare function publishDiscussionViaHttp(token: string, repo: string, title: string, body: string, categoryName?: string): Promise<{ success: boolean; url: string | null; error?: string | null }>;
|
|
38
|
+
export declare function publishDiscussion(repo: string, title: string, body: string, category?: string): Promise<{ success: boolean; url: string | null; error?: string | null }>;
|
|
39
|
+
|
|
40
|
+
export interface StoredDiscussion {
|
|
41
|
+
readonly repo: string;
|
|
42
|
+
readonly number: number | null;
|
|
43
|
+
readonly discussionId?: string | null;
|
|
44
|
+
readonly url: string;
|
|
45
|
+
readonly projectName?: string;
|
|
46
|
+
readonly website?: string;
|
|
47
|
+
readonly title: string;
|
|
48
|
+
readonly lastPublishedAt: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface DiscussionPublishResult {
|
|
52
|
+
readonly success: boolean;
|
|
53
|
+
readonly url: string | null;
|
|
54
|
+
readonly updated?: boolean;
|
|
55
|
+
readonly discussionNumber?: number | null;
|
|
56
|
+
readonly error?: string | null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export declare function getStoredDiscussion(cwd?: string): StoredDiscussion | null;
|
|
60
|
+
export declare function saveStoredDiscussion(data: StoredDiscussion, cwd?: string): boolean;
|
|
61
|
+
export declare function clearStoredDiscussion(cwd?: string): boolean;
|
|
62
|
+
export declare function formatArchiveComment(previousTitle: string, previousBody: string): string;
|
|
63
|
+
export declare function publishOrUpdateDiscussion(
|
|
64
|
+
repo?: string,
|
|
65
|
+
title?: string,
|
|
66
|
+
body?: string,
|
|
67
|
+
category?: string,
|
|
68
|
+
options?: { readonly projectName?: string; readonly website?: string }
|
|
69
|
+
): Promise<DiscussionPublishResult>;
|