@mutmutco/cli 4.5.158 → 4.5.160
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/dist/main.cjs +559 -373
- package/dist/runbook-sweep.cjs +71 -6
- package/package.json +1 -1
package/dist/runbook-sweep.cjs
CHANGED
|
@@ -190,6 +190,54 @@ var init_error_codes = __esm({
|
|
|
190
190
|
}
|
|
191
191
|
});
|
|
192
192
|
|
|
193
|
+
// src/gh-read-route.ts
|
|
194
|
+
function isViewerFreeGhRead(args) {
|
|
195
|
+
if (args.some((a) => VIEWER.test(a))) return false;
|
|
196
|
+
const [group, verb] = args;
|
|
197
|
+
if (group === "api") return isReadOnlyApi(args.slice(1));
|
|
198
|
+
return Boolean(group && verb && READ_VERBS.get(group)?.has(verb));
|
|
199
|
+
}
|
|
200
|
+
function isReadOnlyApi(rest) {
|
|
201
|
+
let path2;
|
|
202
|
+
for (let i = 0; i < rest.length; i++) {
|
|
203
|
+
const a = rest[i];
|
|
204
|
+
if (a === "-X" || a === "--method") {
|
|
205
|
+
if ((rest[i + 1] ?? "").toUpperCase() !== "GET") return false;
|
|
206
|
+
i++;
|
|
207
|
+
} else if (/^--method=/.test(a)) {
|
|
208
|
+
if (a.slice(9).toUpperCase() !== "GET") return false;
|
|
209
|
+
} else if (a === "-f" || a === "-F" || a === "--field" || a === "--raw-field") {
|
|
210
|
+
const field = rest[i + 1] ?? "";
|
|
211
|
+
if (path2 !== "graphql" || !/^query=\s*(query\b|\{)/.test(field) || /projectV2|projectsV2/.test(field)) return false;
|
|
212
|
+
i++;
|
|
213
|
+
} else if (a === "--input" || a.startsWith("--input=")) {
|
|
214
|
+
return false;
|
|
215
|
+
} else if (a === "-H" || a === "--header" || a === "-q" || a === "--jq" || a === "-t" || a === "--template" || a === "--hostname" || a === "--cache") {
|
|
216
|
+
i++;
|
|
217
|
+
} else if (!a.startsWith("-") && path2 === void 0) {
|
|
218
|
+
path2 = a.replace(/^\//, "");
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (!path2) return false;
|
|
222
|
+
if (path2 === "graphql") return rest.some((a) => /^query=\s*(query\b|\{)/.test(a));
|
|
223
|
+
return !/^(user|users\/[^/]+\/|notifications|search\/|orgs\/[^/]+\/projectsV2|graphql)/.test(path2);
|
|
224
|
+
}
|
|
225
|
+
var READ_VERBS, VIEWER;
|
|
226
|
+
var init_gh_read_route = __esm({
|
|
227
|
+
"src/gh-read-route.ts"() {
|
|
228
|
+
"use strict";
|
|
229
|
+
READ_VERBS = /* @__PURE__ */ new Map([
|
|
230
|
+
["pr", /* @__PURE__ */ new Set(["view", "list", "checks", "diff"])],
|
|
231
|
+
["issue", /* @__PURE__ */ new Set(["view", "list"])],
|
|
232
|
+
["run", /* @__PURE__ */ new Set(["view", "list", "watch"])],
|
|
233
|
+
["label", /* @__PURE__ */ new Set(["list"])],
|
|
234
|
+
["release", /* @__PURE__ */ new Set(["view", "list"])],
|
|
235
|
+
["repo", /* @__PURE__ */ new Set(["view"])]
|
|
236
|
+
]);
|
|
237
|
+
VIEWER = /@me\b|viewer|project/i;
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
|
|
193
241
|
// src/github-quota.ts
|
|
194
242
|
var init_github_quota = __esm({
|
|
195
243
|
"src/github-quota.ts"() {
|
|
@@ -237,6 +285,12 @@ var init_stdin_inject = __esm({
|
|
|
237
285
|
});
|
|
238
286
|
|
|
239
287
|
// src/cli-shared.ts
|
|
288
|
+
async function ghReadAppEnv(file, args) {
|
|
289
|
+
if (!ghReadTokenProvider || !/(^|[\\/])gh(\.exe)?$/i.test(file) || process.env.MMI_ACTOR?.trim() === "personal") return void 0;
|
|
290
|
+
if (!isViewerFreeGhRead(args)) return void 0;
|
|
291
|
+
const token = await ghReadTokenProvider().catch(() => void 0);
|
|
292
|
+
return token ? { ...process.env, GH_TOKEN: token } : void 0;
|
|
293
|
+
}
|
|
240
294
|
function killProcessTree(pid) {
|
|
241
295
|
try {
|
|
242
296
|
if (process.platform === "win32") {
|
|
@@ -271,7 +325,7 @@ function execFileHard(file, args, options) {
|
|
|
271
325
|
timer.unref?.();
|
|
272
326
|
});
|
|
273
327
|
}
|
|
274
|
-
var import_node_child_process3, import_node_util2, rawExecFileP, DEFAULT_EXEC_TIMEOUT_MS, execFileP, ExecDeadlineError;
|
|
328
|
+
var import_node_child_process3, import_node_util2, rawExecFileP, DEFAULT_EXEC_TIMEOUT_MS, execFileP, ghReadTokenProvider, ExecDeadlineError;
|
|
275
329
|
var init_cli_shared = __esm({
|
|
276
330
|
"src/cli-shared.ts"() {
|
|
277
331
|
"use strict";
|
|
@@ -282,16 +336,27 @@ var init_cli_shared = __esm({
|
|
|
282
336
|
init_clean_exit();
|
|
283
337
|
init_error_codes();
|
|
284
338
|
init_github_client();
|
|
339
|
+
init_gh_read_route();
|
|
285
340
|
init_hub_auth();
|
|
286
341
|
init_house_map();
|
|
287
342
|
init_stdin_inject();
|
|
288
343
|
rawExecFileP = (0, import_node_util2.promisify)(import_node_child_process3.execFile);
|
|
289
344
|
DEFAULT_EXEC_TIMEOUT_MS = 1e4;
|
|
290
|
-
execFileP = (file, args, options = {}) =>
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
345
|
+
execFileP = async (file, args, options = {}) => {
|
|
346
|
+
const run = (env) => (
|
|
347
|
+
// encoding 'utf8' guarantees string stdout/stderr at runtime; the cast pins the type because
|
|
348
|
+
// promisify(execFile)'s overloads widen to string|Buffer when options is spread in.
|
|
349
|
+
rawExecFileP(file, args, { encoding: "utf8", windowsHide: true, timeout: DEFAULT_EXEC_TIMEOUT_MS, killSignal: "SIGTERM", ...options, ...env ? { env } : {} })
|
|
350
|
+
);
|
|
351
|
+
const appEnv = options.env ? void 0 : await ghReadAppEnv(file, args);
|
|
352
|
+
if (!appEnv) return run();
|
|
353
|
+
try {
|
|
354
|
+
return await run(appEnv);
|
|
355
|
+
} catch (e) {
|
|
356
|
+
if (/Resource not accessible by integration/i.test(String(e.stderr ?? ""))) return run();
|
|
357
|
+
throw e;
|
|
358
|
+
}
|
|
359
|
+
};
|
|
295
360
|
ExecDeadlineError = class extends Error {
|
|
296
361
|
constructor(step, timeoutMs, elapsedMs, killed) {
|
|
297
362
|
super(
|
package/package.json
CHANGED