@coderook/cli 0.8.0 → 0.10.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.
@@ -9,6 +9,20 @@ exports.mergeTrack = mergeTrack;
9
9
  exports.resolveMergeConflict = resolveMergeConflict;
10
10
  exports.applyMerge = applyMerge;
11
11
  exports.cancelMerge = cancelMerge;
12
+ exports.aiAccess = aiAccess;
13
+ exports.setAiAccess = setAiAccess;
14
+ exports.versions = versions;
15
+ exports.issues = issues;
16
+ exports.createIssue = createIssue;
17
+ exports.releases = releases;
18
+ exports.collaborators = collaborators;
19
+ exports.invite = invite;
20
+ exports.watch = watch;
21
+ exports.setWatch = setWatch;
22
+ exports.workflows = workflows;
23
+ exports.tokens = tokens;
24
+ exports.revokeToken = revokeToken;
25
+ exports.deleteProject = deleteProject;
12
26
  /** The small part of the API the command-line tool needs directly. */
13
27
  const identify_js_1 = require("../../desktop-app/src/main/identify.js");
14
28
  const config_js_1 = require("./config.js");
@@ -91,3 +105,146 @@ async function applyMerge(mergeTrackId) {
91
105
  async function cancelMerge(mergeTrackId) {
92
106
  await call(`/v1/merge-tracks/${mergeTrackId}/cancel`, { method: "POST" });
93
107
  }
108
+ /**
109
+ * Read one project's machine-access answers.
110
+ *
111
+ * Taken from the project record rather than a dedicated endpoint, because
112
+ * that is where they live — four columns on the repository, not a separate
113
+ * resource. Defaults to permissive, matching the service: a project that has
114
+ * never been touched allows everything.
115
+ */
116
+ async function aiAccess(repositoryId) {
117
+ const body = await call(`/v1/repositories/${encodeURIComponent(repositoryId)}`);
118
+ const project = (body.repository ?? body);
119
+ const read = (key) => project[key] !== false;
120
+ return {
121
+ aiRead: read("aiRead"),
122
+ aiDownload: read("aiDownload"),
123
+ aiContribute: read("aiContribute"),
124
+ aiRequest: read("aiRequest"),
125
+ };
126
+ }
127
+ /**
128
+ * Change one answer.
129
+ *
130
+ * One at a time, matching the site: each is a separate decision, and sending
131
+ * all four would make turning off downloads look like it needed a view about
132
+ * indexing as well.
133
+ */
134
+ async function setAiAccess(repositoryId, change) {
135
+ await call(`/v1/repositories/${encodeURIComponent(repositoryId)}`, {
136
+ method: "PATCH",
137
+ body: change,
138
+ });
139
+ }
140
+ /** Every saved version of a project, newest first. */
141
+ async function versions(repositoryId) {
142
+ const body = await call(`/v1/repositories/${encodeURIComponent(repositoryId)}/versions`);
143
+ return (body.versions ?? []).map((row) => ({
144
+ id: String(row.id ?? ""),
145
+ sequence: Number(row.sequence ?? 0),
146
+ message: String(row.message ?? ""),
147
+ fileCount: Number(row.fileCount ?? 0),
148
+ storedSize: Number(row.storedSize ?? row.sourceSize ?? 0),
149
+ createdAt: String(row.createdAt ?? ""),
150
+ }));
151
+ }
152
+ async function issues(repositoryId) {
153
+ const body = await call(`/v1/repositories/${encodeURIComponent(repositoryId)}/issues`);
154
+ return {
155
+ issues: (body.issues ?? []).map((row) => ({
156
+ number: Number(row.number ?? 0),
157
+ title: String(row.title ?? ""),
158
+ state: String(row.state ?? "open"),
159
+ labels: Array.isArray(row.labels) ? row.labels : [],
160
+ commentCount: Number(row.commentCount ?? 0),
161
+ createdAt: String(row.createdAt ?? ""),
162
+ })),
163
+ openCount: Number(body.openCount ?? 0),
164
+ closedCount: Number(body.closedCount ?? 0),
165
+ };
166
+ }
167
+ async function createIssue(repositoryId, input) {
168
+ const created = await call(`/v1/repositories/${encodeURIComponent(repositoryId)}/issues`, { method: "POST", body: { title: input.title, body: input.body ?? "" } });
169
+ return { number: Number(created.issue?.number ?? 0) };
170
+ }
171
+ async function releases(repositoryId) {
172
+ const body = await call(`/v1/repositories/${encodeURIComponent(repositoryId)}/releases`);
173
+ return (body.releases ?? []).map((row) => ({
174
+ sequence: Number(row.sequence ?? 0),
175
+ name: String(row.name ?? ""),
176
+ notes: String(row.notes ?? ""),
177
+ releasedAt: String(row.releasedAt ?? ""),
178
+ releasedBy: String(row.releasedBy ?? ""),
179
+ assets: Array.isArray(row.assets) ? row.assets : [],
180
+ }));
181
+ }
182
+ async function collaborators(repositoryId) {
183
+ const body = await call(`/v1/repositories/${encodeURIComponent(repositoryId)}/collaborators`);
184
+ return {
185
+ collaborators: (body.collaborators ?? []).map((row) => ({
186
+ displayName: String(row.displayName ?? ""),
187
+ email: String(row.email ?? ""),
188
+ role: String(row.role ?? "member"),
189
+ })),
190
+ invites: (body.invites ?? []).map((row) => ({
191
+ email: String(row.email ?? ""),
192
+ role: String(row.role ?? "member"),
193
+ expiresAt: String(row.expiresAt ?? row.expires_at ?? ""),
194
+ })),
195
+ };
196
+ }
197
+ async function invite(repositoryId, input) {
198
+ await call(`/v1/repositories/${encodeURIComponent(repositoryId)}/invites`, {
199
+ method: "POST",
200
+ body: input,
201
+ });
202
+ }
203
+ async function watch(repositoryId) {
204
+ const body = await call(`/v1/repositories/${encodeURIComponent(repositoryId)}/watch`);
205
+ return {
206
+ level: String(body.level ?? "versions"),
207
+ inApp: body.inApp !== false,
208
+ desktop: body.desktop === true,
209
+ emailDigest: body.emailDigest === true,
210
+ };
211
+ }
212
+ async function setWatch(repositoryId, change) {
213
+ await call(`/v1/repositories/${encodeURIComponent(repositoryId)}/watch`, {
214
+ method: "PUT",
215
+ body: change,
216
+ });
217
+ }
218
+ async function workflows(repositoryId) {
219
+ const body = await call(`/v1/repositories/${encodeURIComponent(repositoryId)}/workflows`);
220
+ return (body.workflows ?? []).map((row) => ({
221
+ name: String(row.name ?? ""),
222
+ trigger: String(row.trigger ?? ""),
223
+ command: String(row.command ?? ""),
224
+ runsOn: String(row.runsOn ?? "hosted"),
225
+ runs: Number(row.runs ?? 0),
226
+ passing: Number(row.passing ?? 0),
227
+ archivedAt: row.archivedAt ? String(row.archivedAt) : null,
228
+ }));
229
+ }
230
+ /** Personal access tokens on the account. */
231
+ async function tokens() {
232
+ const body = await call("/v1/account/tokens");
233
+ return (body.tokens ?? []).map((row) => ({
234
+ id: String(row.id ?? ""),
235
+ name: String(row.name ?? ""),
236
+ lastUsedAt: String(row.lastUsedAt ?? ""),
237
+ createdAt: String(row.createdAt ?? ""),
238
+ }));
239
+ }
240
+ async function revokeToken(tokenId) {
241
+ await call(`/v1/account/tokens/${encodeURIComponent(tokenId)}`, {
242
+ method: "DELETE",
243
+ });
244
+ }
245
+ /** Remove a project. The service keeps it for its retention window. */
246
+ async function deleteProject(repositoryId) {
247
+ await call(`/v1/repositories/${encodeURIComponent(repositoryId)}`, {
248
+ method: "DELETE",
249
+ });
250
+ }