@bensandee/forgejo-cli 0.6.0 → 0.6.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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/bin.mjs +143 -230
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -48,7 +48,7 @@ command takes `--json`, which prints exactly one JSON document, failures include
48
48
  | `pr:list` | List a repository's pull requests |
49
49
  | `commit:status` | Read the status checks for a commit SHA, branch, tag or git ref |
50
50
  | `issue:*` | `view`, `list`, `comment`, `create`, `update`, `download`, `label`, `unlabel`, `set-labels`, `close`, `reopen` |
51
- | `pr:create` | Push the current branch and open a pull request, deriving the title and body when none is given |
51
+ | `pr:create` | Push the current branch and open a pull request, deriving the title and body when none is given; reports no closed-issue claims, which `bst pr:create` does |
52
52
  | `pr:update` | Push the current branch and update its open pull request |
53
53
  | `branch:list` | List a repository's branches |
54
54
  | `branch:delete` | Delete a branch through the API; reports the forge's reason when it refuses |
package/dist/bin.mjs CHANGED
@@ -6,7 +6,7 @@ import { FatalError, TransientError, UnexpectedError, describeError, redact, red
6
6
  import { z } from "zod";
7
7
  import { defineCommand, renderUsage, runCommand, runMain } from "citty";
8
8
  import { execFileSync, spawn } from "node:child_process";
9
- //#region ../cli-kit/src/json.ts
9
+ // ../cli-kit/src/json.ts
10
10
  function resolveJsonMode(rawArgs) {
11
11
  if (!rawArgs.some(requestsJson)) return false;
12
12
  if (rawArgs.includes("--help") || rawArgs.includes("-h")) return false;
@@ -100,8 +100,7 @@ function classifyThrown(error, verbose) {
100
100
  detail
101
101
  };
102
102
  }
103
- //#endregion
104
- //#region ../cli-kit/src/env-file.ts
103
+ // ../cli-kit/src/env-file.ts
105
104
  const ENV_FILE_VAR = "BST_ENV_FILE";
106
105
  function loadEnvFileFromEnv() {
107
106
  const raw = process.env[ENV_FILE_VAR]?.trim();
@@ -158,11 +157,10 @@ function loadEnvFileForBin(rawArgs, bin, io = processIo) {
158
157
  return io.exit(1);
159
158
  }
160
159
  }
161
- //#endregion
162
- //#region src/version.ts
160
+ // src/version.ts
163
161
  const parsed = z.object({ version: z.string() }).safeParse({
164
162
  name: "@bensandee/forgejo-cli",
165
- version: "0.6.0",
163
+ version: "0.6.2",
166
164
  description: "bst-fj: Forgejo API commands without the rest of bst",
167
165
  license: "MIT",
168
166
  repository: {
@@ -203,14 +201,12 @@ const parsed = z.object({ version: z.string() }).safeParse({
203
201
  });
204
202
  if (!parsed.success) throw new UnexpectedError(`@bensandee/forgejo-cli's package.json has no string version.`);
205
203
  const BST_FJ_VERSION = parsed.data.version;
206
- //#endregion
207
- //#region src/env-file-preload.ts
204
+ // src/env-file-preload.ts
208
205
  const envFileLoad = loadEnvFileForBin(process.argv.slice(2), {
209
206
  name: "bst-fj",
210
207
  version: BST_FJ_VERSION
211
208
  });
212
- //#endregion
213
- //#region ../cli-kit/src/logger.ts
209
+ // ../cli-kit/src/logger.ts
214
210
  const RANK = {
215
211
  error: 0,
216
212
  warn: 1,
@@ -310,8 +306,7 @@ function createLogger(options = {}) {
310
306
  });
311
307
  }
312
308
  const rootLogger = createLogger();
313
- //#endregion
314
- //#region ../cli-kit/src/flags.ts
309
+ // ../cli-kit/src/flags.ts
315
310
  const UNIVERSAL_FLAGS = [
316
311
  "--help",
317
312
  "-h",
@@ -648,8 +643,7 @@ function parseLimitFlag(raw) {
648
643
  if (!Number.isInteger(value) || value < 1) throw new FatalError(`--limit must be a positive integer, got "${raw}"`);
649
644
  return value;
650
645
  }
651
- //#endregion
652
- //#region ../cli-kit/src/output.ts
646
+ // ../cli-kit/src/output.ts
653
647
  const stdout = (msg) => console.log(msg);
654
648
  function initialState() {
655
649
  return {
@@ -712,8 +706,7 @@ function flushJsonOutput() {
712
706
  function jsonDocumentWritten() {
713
707
  return state.wrote;
714
708
  }
715
- //#endregion
716
- //#region ../cli-kit/src/path-probe.ts
709
+ // ../cli-kit/src/path-probe.ts
717
710
  function probeCliPath(value) {
718
711
  try {
719
712
  const stat = statSync(value, { throwIfNoEntry: false });
@@ -723,8 +716,7 @@ function probeCliPath(value) {
723
716
  return "missing";
724
717
  }
725
718
  }
726
- //#endregion
727
- //#region ../cli-kit/src/run.ts
719
+ // ../cli-kit/src/run.ts
728
720
  function classifyWithHook(error, verbose, hook) {
729
721
  const classified = classifyThrown(error, verbose);
730
722
  const worded = hook?.(error);
@@ -878,8 +870,7 @@ const log = {
878
870
  current.debug(message);
879
871
  }
880
872
  };
881
- //#endregion
882
- //#region ../forgejo/src/connection.ts
873
+ // ../forgejo/src/connection.ts
883
874
  function parseGitUrl(urlStr) {
884
875
  try {
885
876
  const url = new URL(urlStr);
@@ -1006,14 +997,12 @@ function normalizeGitUrl(raw) {
1006
997
  return null;
1007
998
  }
1008
999
  }
1009
- //#endregion
1010
- //#region src/describe-forge-error.ts
1000
+ // src/describe-forge-error.ts
1011
1001
  function describeForgeError(error) {
1012
1002
  if (error instanceof RepoTargetEmptyError) return "--repo was given with no repository URL (expected e.g. https://host/owner/repo).";
1013
1003
  if (error instanceof RepoTargetMismatchError) return `--repo disagrees with the issue URL: --repo names ${error.given}, the issue URL names ${error.fromReference}.`;
1014
1004
  }
1015
- //#endregion
1016
- //#region ../forgejo/src/fetch-retry.ts
1005
+ // ../forgejo/src/fetch-retry.ts
1017
1006
  const DEFAULT_RETRY_POLICY = {
1018
1007
  attempts: 5,
1019
1008
  baseDelayMs: 250,
@@ -1070,13 +1059,11 @@ function fetchWithRetry(fetchImpl, policy = DEFAULT_RETRY_POLICY, defaultTimeout
1070
1059
  function createForgeFetcher(policy = DEFAULT_RETRY_POLICY) {
1071
1060
  return { fetch: fetchWithRetry((input, init) => globalThis.fetch(input, init), policy) };
1072
1061
  }
1073
- //#endregion
1074
- //#region src/fetcher.ts
1062
+ // src/fetcher.ts
1075
1063
  function cliFetcher() {
1076
1064
  return createForgeFetcher();
1077
1065
  }
1078
- //#endregion
1079
- //#region ../forgejo/src/errors.ts
1066
+ // ../forgejo/src/errors.ts
1080
1067
  var ForgeAccessError = class extends FatalError {};
1081
1068
  function authHeaders(conn) {
1082
1069
  return { Authorization: `token ${conn.token}` };
@@ -1173,8 +1160,7 @@ async function throwForgejoFailure(res, operation, notFoundMessage) {
1173
1160
  if (res.status === 410) throw new FatalError(`${message}\nForgejo returned 410 Gone -- issues are likely disabled on this repository; retrying will not help.`);
1174
1161
  throw new TransientError(message);
1175
1162
  }
1176
- //#endregion
1177
- //#region ../forgejo/src/commit-status.ts
1163
+ // ../forgejo/src/commit-status.ts
1178
1164
  const CombinedStatusSchema = z.object({
1179
1165
  state: z.string(),
1180
1166
  statuses: z.array(z.unknown())
@@ -1297,6 +1283,7 @@ z.array(z.unknown());
1297
1283
  function branchNotFoundMessage(conn, branch) {
1298
1284
  return `Branch ${branch} not found in ${conn.repository}`;
1299
1285
  }
1286
+ z.object({ full_name: z.string() });
1300
1287
  async function getBranchHeadSha(executor, conn, branch) {
1301
1288
  const url = `${repoBase(conn)}/branches/${encodeURIComponent(branch)}`;
1302
1289
  const res = await executor.fetch(url, { headers: authHeaders(conn) });
@@ -1318,8 +1305,7 @@ async function branchExists(executor, conn, branch) {
1318
1305
  }, branchNotFoundMessage(conn, branch));
1319
1306
  return true;
1320
1307
  }
1321
- //#endregion
1322
- //#region ../cli-kit/src/git.ts
1308
+ // ../cli-kit/src/git.ts
1323
1309
  const BRANCH_REF_PREFIX = "refs/heads/";
1324
1310
  const ORIGIN_READ_TIMEOUT_MS = 5e3;
1325
1311
  function defaultGitRunner(args, cwd, options) {
@@ -1382,8 +1368,7 @@ function readPackageRepositoryUrl(cwd) {
1382
1368
  if (!repo) return null;
1383
1369
  return typeof repo === "string" ? repo : repo.url;
1384
1370
  }
1385
- //#endregion
1386
- //#region src/connection.ts
1371
+ // src/connection.ts
1387
1372
  function resolveRepoUrl(cwd) {
1388
1373
  return resolveRepoUrlFrom(() => readOriginUrl(cwd), () => readPackageRepositoryUrl(cwd));
1389
1374
  }
@@ -1405,8 +1390,7 @@ function requireForgejoTarget(cwd, target, githubRefusal, env = process.env) {
1405
1390
  if (conn === null) throw new FatalError(githubRefusal);
1406
1391
  return conn;
1407
1392
  }
1408
- //#endregion
1409
- //#region ../forgejo/src/check-poll.ts
1393
+ // ../forgejo/src/check-poll.ts
1410
1394
  function classifyBaseStatus(checks) {
1411
1395
  if (!checks.parsed) return "unparseable";
1412
1396
  if (checks.contexts.length === 0) return "no-status";
@@ -1493,16 +1477,14 @@ function renderCheckLine(check) {
1493
1477
  if (check.verdict === "red" && check.targetUrl !== null) line += ` (${check.targetUrl})`;
1494
1478
  return line;
1495
1479
  }
1496
- //#endregion
1497
- //#region ../cli-kit/src/env-override.ts
1480
+ // ../cli-kit/src/env-override.ts
1498
1481
  function envMsOverride(raw, productionMs) {
1499
1482
  if (raw === void 0) return productionMs;
1500
1483
  const parsed = Number(raw.trim());
1501
1484
  if (!Number.isSafeInteger(parsed) || parsed <= 0) return productionMs;
1502
1485
  return Math.min(parsed, productionMs);
1503
1486
  }
1504
- //#endregion
1505
- //#region src/poll-timings.ts
1487
+ // src/poll-timings.ts
1506
1488
  const DEFAULT_TIMEOUT_MS = 12e5;
1507
1489
  const DEFAULT_INTERVAL_MS = 15e3;
1508
1490
  const MIN_INTERVAL_MS = 5e3;
@@ -1514,15 +1496,13 @@ function resolvePollTimings(options) {
1514
1496
  intervalMs: envMsOverride(process.env["BST_TEST_CHECK_POLL_INTERVAL_MS"], Math.max(requestedIntervalMs, MIN_INTERVAL_MS))
1515
1497
  };
1516
1498
  }
1517
- //#endregion
1518
- //#region src/sleep.ts
1499
+ // src/sleep.ts
1519
1500
  function sleep(ms) {
1520
1501
  return new Promise((resolve) => {
1521
1502
  setTimeout(resolve, ms);
1522
1503
  });
1523
1504
  }
1524
- //#endregion
1525
- //#region src/commit-status.ts
1505
+ // src/commit-status.ts
1526
1506
  async function resolveCommitStatusTarget(fetcher, options) {
1527
1507
  const targetRepo = parseRepoTarget(options.repo);
1528
1508
  const conn = requireForgejoTarget(options.cwd, targetRepo, "commit:status is Forgejo-only: GitHub Actions publishes check runs, not commit statuses. Use `gh run list` / `gh run view` instead.");
@@ -1632,8 +1612,7 @@ function renderCommitStatus(report) {
1632
1612
  lines.push(summaryParts.join(" -- "));
1633
1613
  return lines.join("\n");
1634
1614
  }
1635
- //#endregion
1636
- //#region src/commands/commit-status.ts
1615
+ // src/commands/commit-status.ts
1637
1616
  const commitStatusCommand = defineCommand({
1638
1617
  meta: {
1639
1618
  name: "commit:status",
@@ -1687,8 +1666,37 @@ const commitStatusCommand = defineCommand({
1687
1666
  process.exitCode = report.status === "green" ? 0 : 1;
1688
1667
  }
1689
1668
  });
1690
- //#endregion
1691
- //#region ../forgejo/src/fetcher.ts
1669
+ // ../forgejo/src/closing-refs.ts
1670
+ const CLOSING_REF = /(?:^|[\s([])(clos(?:e|es|ed)|fix(?:es|ed)?|resolv(?:e|es|ed))(?::[ \t]*|[ \t]+)((?:[\w.-]+\/[\w.-]+)?#\d+)(?![\w-])/gim;
1671
+ function capitalize(word) {
1672
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
1673
+ }
1674
+ function extractClosingRefs(messages) {
1675
+ const byIssue = /* @__PURE__ */ new Map();
1676
+ for (const message of messages) for (const [, keyword, issue] of message.matchAll(CLOSING_REF)) {
1677
+ if (keyword === void 0 || issue === void 0) continue;
1678
+ const key = issue.toLowerCase();
1679
+ if (!byIssue.has(key)) byIssue.set(key, {
1680
+ text: `${capitalize(keyword)} ${issue}`,
1681
+ issue
1682
+ });
1683
+ }
1684
+ return [...byIssue.values()];
1685
+ }
1686
+ function closedIssues(text) {
1687
+ return new Set(extractClosingRefs([text]).map((ref) => ref.issue.toLowerCase()));
1688
+ }
1689
+ function droppedClosingRefs(messages, body) {
1690
+ const closed = closedIssues(body);
1691
+ return extractClosingRefs(messages).filter((ref) => !closed.has(ref.issue.toLowerCase()));
1692
+ }
1693
+ function carryForwardClosingRefs(source, target) {
1694
+ const missing = droppedClosingRefs([source], target);
1695
+ if (missing.length === 0) return target;
1696
+ const refLines = missing.map((ref) => ref.text).join("\n");
1697
+ return target.trim() === "" ? refLines : `${target}\n\n${refLines}`;
1698
+ }
1699
+ // ../forgejo/src/fetcher.ts
1692
1700
  const LONG_FETCH_TIMEOUT_MS = 6e5;
1693
1701
  function morePagesFollow(res, pageLength, received, pageSize) {
1694
1702
  if (pageLength === 0) return false;
@@ -1697,8 +1705,7 @@ function morePagesFollow(res, pageLength, received, pageSize) {
1697
1705
  if (!Number.isSafeInteger(total) || total < 0) return pageLength >= pageSize;
1698
1706
  return received < total;
1699
1707
  }
1700
- //#endregion
1701
- //#region ../forgejo/src/label-provisioning.ts
1708
+ // ../forgejo/src/label-provisioning.ts
1702
1709
  const LabelSchema = z.object({
1703
1710
  id: z.number(),
1704
1711
  name: z.string(),
@@ -1871,8 +1878,7 @@ async function deleteForgejoLabel(executor, conn, id) {
1871
1878
  resource: String(id)
1872
1879
  }, repoNotFoundMessage(conn));
1873
1880
  }
1874
- //#endregion
1875
- //#region ../forgejo/src/issues.ts
1881
+ // ../forgejo/src/issues.ts
1876
1882
  const IssueResponseSchema = z.object({
1877
1883
  number: z.number(),
1878
1884
  title: z.string(),
@@ -1931,13 +1937,15 @@ const DependencyResponseSchema = z.object({
1931
1937
  });
1932
1938
  z.array(DependencyResponseSchema);
1933
1939
  function issueListParams(type, query) {
1934
- const params = new URLSearchParams(type === "all" ? {} : { type });
1940
+ const kind = query.type ?? type;
1941
+ const params = new URLSearchParams(kind === "all" ? {} : { type: kind });
1935
1942
  params.set("state", query.state);
1936
1943
  params.set("limit", String(query.limit));
1937
1944
  if (query.label !== void 0) params.set("labels", query.label);
1938
1945
  if (query.page !== void 0) params.set("page", String(query.page));
1939
1946
  if (query.since !== void 0) params.set("since", query.since);
1940
1947
  if (query.sort !== void 0) params.set("sort", query.sort);
1948
+ if (query.q !== void 0) params.set("q", query.q);
1941
1949
  return params;
1942
1950
  }
1943
1951
  async function fetchIssueListPage(executor, conn, params) {
@@ -2089,8 +2097,7 @@ async function setForgejoIssueState(executor, conn, number, state) {
2089
2097
  }, issueNotFoundMessage(conn, number));
2090
2098
  return normalizeIssue(parseIssueOrThrow(await res.json()));
2091
2099
  }
2092
- //#endregion
2093
- //#region ../forgejo/src/label-sync.ts
2100
+ // ../forgejo/src/label-sync.ts
2094
2101
  function resolveSyncMode(check, dryRun) {
2095
2102
  if (check) return "check";
2096
2103
  if (dryRun) return "dry-run";
@@ -2264,8 +2271,7 @@ function syncSummaryLines(result) {
2264
2271
  failureLines: result.failures.map((failure) => `${failure.repository}: failed: ${failure.error}`)
2265
2272
  };
2266
2273
  }
2267
- //#endregion
2268
- //#region src/label-sets-file.ts
2274
+ // src/label-sets-file.ts
2269
2275
  function readLabelSet(path, setName) {
2270
2276
  let raw;
2271
2277
  try {
@@ -2292,8 +2298,7 @@ function readLabelSet(path, setName) {
2292
2298
  }
2293
2299
  return specs;
2294
2300
  }
2295
- //#endregion
2296
- //#region src/labels.ts
2301
+ // src/labels.ts
2297
2302
  async function runLabelsList(fetcher, conn) {
2298
2303
  const labels = await fetchAllForgejoLabels(fetcher, conn);
2299
2304
  return {
@@ -2327,8 +2332,7 @@ function renderSync(result) {
2327
2332
  for (const line of repoLines) rootLogger.info(line);
2328
2333
  for (const line of failureLines) rootLogger.warn(line);
2329
2334
  }
2330
- //#endregion
2331
- //#region src/commands/labels.ts
2335
+ // src/commands/labels.ts
2332
2336
  const GITHUB_REFUSAL = "bst-fj labels requires a Forgejo repository";
2333
2337
  const listCommand$1 = defineCommand({
2334
2338
  meta: {
@@ -2435,8 +2439,7 @@ const labelsCommand = defineCommand({
2435
2439
  sync: syncCommand
2436
2440
  }
2437
2441
  });
2438
- //#endregion
2439
- //#region ../forgejo/src/releases.ts
2442
+ // ../forgejo/src/releases.ts
2440
2443
  const SETTLE_ATTEMPTS = 4;
2441
2444
  const SETTLE_BASE_DELAY_MS = 2e3;
2442
2445
  const SETTLE_MAX_DELAY_MS = 16e3;
@@ -2658,8 +2661,7 @@ z.looseObject({
2658
2661
  created: z.string().nullish()
2659
2662
  })
2660
2663
  });
2661
- //#endregion
2662
- //#region src/commands/release-create.ts
2664
+ // src/commands/release-create.ts
2663
2665
  const releaseCreateCommand = defineCommand({
2664
2666
  meta: {
2665
2667
  name: "release:create",
@@ -2708,8 +2710,7 @@ const releaseCreateCommand = defineCommand({
2708
2710
  else rootLogger.info(`Created Forgejo release for ${args.tag}`);
2709
2711
  }
2710
2712
  });
2711
- //#endregion
2712
- //#region ../forgejo/src/secrets.ts
2713
+ // ../forgejo/src/secrets.ts
2713
2714
  const ActionSecretListSchema = z.array(z.object({ name: z.string() }));
2714
2715
  const SECRETS_PAGE_SIZE = 50;
2715
2716
  const SECRETS_MAX_PAGES = 20;
@@ -2765,8 +2766,7 @@ async function deleteActionSecret(executor, conn, secretName) {
2765
2766
  resource: secretName
2766
2767
  }));
2767
2768
  }
2768
- //#endregion
2769
- //#region src/secrets.ts
2769
+ // src/secrets.ts
2770
2770
  async function runSecretsSet(fetcher, config) {
2771
2771
  if (!isValidSecretName(config.secretName)) throw new FatalError(`Invalid secret name "${config.secretName}". A name must match [A-Za-z_][A-Za-z0-9_]* and must not start with FORGEJO_, GITEA_, GITHUB_, or a digit.`);
2772
2772
  if (config.dryRun) {
@@ -2808,8 +2808,7 @@ async function runSecretsDelete(fetcher, config) {
2808
2808
  repository: config.conn.repository
2809
2809
  };
2810
2810
  }
2811
- //#endregion
2812
- //#region src/commands/secrets.ts
2811
+ // src/commands/secrets.ts
2813
2812
  function readSecretValue(body) {
2814
2813
  if (body) return body;
2815
2814
  try {
@@ -2938,8 +2937,7 @@ const secretsCommand = defineCommand({
2938
2937
  delete: deleteCommand
2939
2938
  }
2940
2939
  });
2941
- //#endregion
2942
- //#region ../forgejo/src/user.ts
2940
+ // ../forgejo/src/user.ts
2943
2941
  const AuthenticatedUserSchema = z.object({
2944
2942
  login: z.string(),
2945
2943
  email: z.string().nullish()
@@ -2962,8 +2960,7 @@ async function getAuthenticatedUser(executor, conn, signal = null) {
2962
2960
  email: parsed.data.email || null
2963
2961
  };
2964
2962
  }
2965
- //#endregion
2966
- //#region ../forgejo/src/webhooks.ts
2963
+ // ../forgejo/src/webhooks.ts
2967
2964
  const WebhookSchema = z.object({
2968
2965
  id: z.number(),
2969
2966
  type: z.string(),
@@ -3044,8 +3041,7 @@ async function searchRepos(executor, conn) {
3044
3041
  return parsed.data.data;
3045
3042
  })).map((r) => r.full_name);
3046
3043
  }
3047
- //#endregion
3048
- //#region src/commands/webhooks.ts
3044
+ // src/commands/webhooks.ts
3049
3045
  function collectGroup(label, scopeHint, status) {
3050
3046
  if (status.status === "ok") return status.hooks.length > 0 ? {
3051
3047
  label,
@@ -3121,8 +3117,7 @@ const webhooksCommand = defineCommand({
3121
3117
  renderText(inventory, conn.serverUrl);
3122
3118
  }
3123
3119
  });
3124
- //#endregion
3125
- //#region ../forgejo/src/actions.ts
3120
+ // ../forgejo/src/actions.ts
3126
3121
  function forgeTimestamp(value) {
3127
3122
  if (value === null || value === void 0 || value === "") return null;
3128
3123
  const ms = Date.parse(value);
@@ -3300,8 +3295,7 @@ async function dispatchWorkflow(executor, conn, options) {
3300
3295
  inputs: options.inputs
3301
3296
  };
3302
3297
  }
3303
- //#endregion
3304
- //#region ../forgejo/src/actions-log.ts
3298
+ // ../forgejo/src/actions-log.ts
3305
3299
  const CSI_SEQUENCE = /\u001b\[[0-?]*[ -/]*[@-~]/gu;
3306
3300
  const OSC_SEQUENCE = /\u001b\][^\u0007]*(?:\u0007|\u001b\\)/gu;
3307
3301
  const LONE_ESCAPE = /\u001b/gu;
@@ -3343,8 +3337,7 @@ function readActionsJobLog(text) {
3343
3337
  lines
3344
3338
  };
3345
3339
  }
3346
- //#endregion
3347
- //#region src/ci-log.ts
3340
+ // src/ci-log.ts
3348
3341
  const ACTIONS_RUN_URL = /\/actions\/runs\/(\d+)\/?(?:[?#]|$)/u;
3349
3342
  function parseCiLogTarget(target) {
3350
3343
  if (/^\d+$/.test(target)) return {
@@ -3435,8 +3428,7 @@ function renderCiLog(result) {
3435
3428
  for (const line of result.lines) lines.push(line.at === null ? line.text : `${line.at} ${line.text}`);
3436
3429
  return lines.join("\n");
3437
3430
  }
3438
- //#endregion
3439
- //#region src/commands/ci-log.ts
3431
+ // src/commands/ci-log.ts
3440
3432
  const ciLogCommand = defineCommand({
3441
3433
  meta: {
3442
3434
  name: "ci:log",
@@ -3490,8 +3482,7 @@ const ciLogCommand = defineCommand({
3490
3482
  out.text(renderCiLog(result));
3491
3483
  }
3492
3484
  });
3493
- //#endregion
3494
- //#region src/ci-runs.ts
3485
+ // src/ci-runs.ts
3495
3486
  function resolveRunsRef(ref, pr) {
3496
3487
  if (ref !== void 0 && pr !== void 0) throw new FatalError("--ref and --pr are the same filter -- give one of them (--pr 273 for a pull request's own runs, --ref main for a branch's).");
3497
3488
  if (pr !== void 0) {
@@ -3567,8 +3558,7 @@ function renderCiRuns(result) {
3567
3558
  }
3568
3559
  return lines.join("\n");
3569
3560
  }
3570
- //#endregion
3571
- //#region src/commands/ci-runs.ts
3561
+ // src/commands/ci-runs.ts
3572
3562
  const ciRunsCommand = defineCommand({
3573
3563
  meta: {
3574
3564
  name: "ci:runs",
@@ -3633,8 +3623,7 @@ const ciRunsCommand = defineCommand({
3633
3623
  out.text(renderCiRuns(result));
3634
3624
  }
3635
3625
  });
3636
- //#endregion
3637
- //#region ../cli-kit/src/workflow-inputs.ts
3626
+ // ../cli-kit/src/workflow-inputs.ts
3638
3627
  const INPUT_FLAG = "--input";
3639
3628
  const INPUT_FLAG_EQ = "--input=";
3640
3629
  function collectInputArgs(rawArgs) {
@@ -3661,8 +3650,7 @@ function parseInputs(raw) {
3661
3650
  }
3662
3651
  return inputs;
3663
3652
  }
3664
- //#endregion
3665
- //#region src/workflow-dispatch.ts
3653
+ // src/workflow-dispatch.ts
3666
3654
  async function runWorkflowDispatch(fetcher, options) {
3667
3655
  const dispatched = await dispatchWorkflow(fetcher, requireForgejoTarget(options.cwd, void 0, "workflow:dispatch is Forgejo-only -- use gh workflow run on GitHub."), {
3668
3656
  ...options.repo === void 0 ? {} : { repository: options.repo },
@@ -3679,8 +3667,7 @@ async function runWorkflowDispatch(fetcher, options) {
3679
3667
  inputs: dispatched.inputs
3680
3668
  };
3681
3669
  }
3682
- //#endregion
3683
- //#region src/registry-actions.ts
3670
+ // src/registry-actions.ts
3684
3671
  const actionsSubCommands = {
3685
3672
  "ci:log": ciLogCommand,
3686
3673
  "ci:runs": ciRunsCommand,
@@ -3749,8 +3736,7 @@ const DirEntrySchema = z.looseObject({
3749
3736
  type: z.string()
3750
3737
  });
3751
3738
  z.array(DirEntrySchema);
3752
- //#endregion
3753
- //#region ../forgejo/src/branches.ts
3739
+ // ../forgejo/src/branches.ts
3754
3740
  const BranchEntrySchema = z.object({
3755
3741
  name: z.string(),
3756
3742
  protected: z.boolean().optional(),
@@ -3829,8 +3815,7 @@ async function deleteBranch(executor, conn, branch) {
3829
3815
  resource: `${conn.repository}/${branch}`
3830
3816
  });
3831
3817
  }
3832
- //#endregion
3833
- //#region src/branch.ts
3818
+ // src/branch.ts
3834
3819
  const REFUSAL_WORDS = {
3835
3820
  forbidden: "forbidden",
3836
3821
  locked: "locked",
@@ -3856,8 +3841,7 @@ function renderBranchList(listing) {
3856
3841
  if (listing.truncated) lines.push("Listing truncated at the page cap; more branches exist.");
3857
3842
  return lines.join("\n");
3858
3843
  }
3859
- //#endregion
3860
- //#region src/registry-branch.ts
3844
+ // src/registry-branch.ts
3861
3845
  const branchSubCommands = {
3862
3846
  "branch:delete": defineCommand({
3863
3847
  meta: {
@@ -3927,8 +3911,7 @@ const branchSubCommands = {
3927
3911
  }
3928
3912
  })
3929
3913
  };
3930
- //#endregion
3931
- //#region ../cli-kit/src/body-source.ts
3914
+ // ../cli-kit/src/body-source.ts
3932
3915
  function tryRead(read, label) {
3933
3916
  try {
3934
3917
  return read();
@@ -3948,8 +3931,7 @@ function readBodySource(body, bodyFile, options = {}) {
3948
3931
  if (!existsSync(bodyFile)) throw new FatalError(`${flags.file} not found: ${bodyFile}`);
3949
3932
  return tryRead(() => readFileSync(bodyFile, "utf-8"), `${flags.file} "${bodyFile}"`);
3950
3933
  }
3951
- //#endregion
3952
- //#region ../forgejo/src/issue-comments.ts
3934
+ // ../forgejo/src/issue-comments.ts
3953
3935
  const CommentResponseSchema = z.object({
3954
3936
  id: z.number(),
3955
3937
  body: z.string().nullish(),
@@ -4023,8 +4005,7 @@ async function addForgejoComment(executor, conn, number, body) {
4023
4005
  }, issueNotFoundMessage(conn, number));
4024
4006
  return normalizeComment(parseCommentOrThrow(await res.json()));
4025
4007
  }
4026
- //#endregion
4027
- //#region ../forgejo/src/pr-title.ts
4008
+ // ../forgejo/src/pr-title.ts
4028
4009
  const WIP_PREFIXES = ["WIP:", "[WIP]"];
4029
4010
  function hasWipPrefix(title) {
4030
4011
  return matchedWipPrefix(title) !== void 0;
@@ -4038,8 +4019,7 @@ function stripWipPrefix(title) {
4038
4019
  if (prefix === void 0) return title;
4039
4020
  return title.slice(prefix.length).trimStart();
4040
4021
  }
4041
- //#endregion
4042
- //#region ../forgejo/src/pr.ts
4022
+ // ../forgejo/src/pr.ts
4043
4023
  const CreatedPrSchema = z.object({
4044
4024
  number: z.number(),
4045
4025
  html_url: z.string().optional()
@@ -4075,7 +4055,10 @@ async function findOpenPr(executor, conn, head, signal = null) {
4075
4055
  const PullListItemSchema = z.object({
4076
4056
  number: z.number(),
4077
4057
  title: z.string().nullish(),
4078
- head: z.object({ ref: z.string() }),
4058
+ head: z.object({
4059
+ ref: z.string(),
4060
+ repo: z.object({ full_name: z.string() }).nullish()
4061
+ }),
4079
4062
  base: z.object({ ref: z.string() }).nullish(),
4080
4063
  state: z.enum(["open", "closed"]),
4081
4064
  merged: z.boolean().nullish(),
@@ -4090,9 +4073,12 @@ function updatedBefore(since) {
4090
4073
  return (pr) => pr.updatedAt !== null && Date.parse(pr.updatedAt) < since;
4091
4074
  }
4092
4075
  async function listPulls(executor, conn, options = {}) {
4076
+ const startPage = options.startPage ?? 1;
4077
+ if (!Number.isInteger(startPage) || startPage < 1) throw new FatalError(`Cannot list PRs on ${conn.repository}: startPage must be an integer of at least 1, got ${String(startPage)}`);
4078
+ const lastPage = startPage + PULLS_MAX_PAGES - 1;
4093
4079
  const headers = { Authorization: `token ${conn.token}` };
4094
4080
  const pulls = [];
4095
- for (let page = 1; page <= PULLS_MAX_PAGES; page++) {
4081
+ for (let page = startPage; page <= lastPage; page++) {
4096
4082
  options.signal?.throwIfAborted();
4097
4083
  const params = new URLSearchParams({
4098
4084
  state: options.state ?? "all",
@@ -4117,6 +4103,7 @@ async function listPulls(executor, conn, options = {}) {
4117
4103
  number: pr.number,
4118
4104
  title: pr.title ?? null,
4119
4105
  headRef: pr.head.ref,
4106
+ headRepo: pr.head.repo?.full_name ?? null,
4120
4107
  baseRef: pr.base?.ref ?? null,
4121
4108
  state: pr.state,
4122
4109
  merged: pr.merged ?? pr.merged_at != null,
@@ -4132,9 +4119,9 @@ async function listPulls(executor, conn, options = {}) {
4132
4119
  if (options.stopWhen !== void 0 && items.some(options.stopWhen)) break;
4133
4120
  if (options.updatedSince !== void 0 && items.some(updatedBefore(options.updatedSince))) break;
4134
4121
  if (options.limit !== void 0 && pulls.length >= options.limit) break;
4135
- if (page === PULLS_MAX_PAGES) {
4122
+ if (page === lastPage) {
4136
4123
  log.warn(`PR listing on ${conn.repository} hit the ${String(PULLS_MAX_PAGES)}-page cap without an empty page; results may be truncated`);
4137
- options.onPageCap?.();
4124
+ options.onPageCap?.(lastPage);
4138
4125
  }
4139
4126
  }
4140
4127
  return pulls;
@@ -4306,8 +4293,7 @@ const PullReviewCommentSchema = z.object({
4306
4293
  user: z.object({ login: z.string() }).nullish()
4307
4294
  });
4308
4295
  z.array(PullReviewCommentSchema);
4309
- //#endregion
4310
- //#region ../forgejo/src/issue-api.ts
4296
+ // ../forgejo/src/issue-api.ts
4311
4297
  var IssueNumberRequiredError = class extends FatalError {
4312
4298
  constructor() {
4313
4299
  super("An issue number or issue URL is required.");
@@ -4334,8 +4320,7 @@ function forgejoIssueApi(fetcher, conn) {
4334
4320
  pullRequest: (number) => getForgejoPrDetail(fetcher, conn, number)
4335
4321
  };
4336
4322
  }
4337
- //#endregion
4338
- //#region ../forgejo/src/issue-messages.ts
4323
+ // ../forgejo/src/issue-messages.ts
4339
4324
  const ISSUE_LIST_JSON_HELP = "Emit one JSON document: issues ([{number, title, state, url, author, labels, createdAt, updatedAt, closedAt (null while open), isPullRequest, assignees, attachments ([{id, name, size, createdAt, downloadUrl}])}]), truncated.";
4340
4325
  const ISSUE_CREATE_JSON_HELP = "Emit one JSON document: number, url, assignees. A dry run reports number 0 and an empty url.";
4341
4326
  const ISSUE_STATE_JSON_HELP = "Emit one JSON document: number, url, action (close | reopen), state ({previous, current}), changed, comment? ({posted}; present only when a comment was given).";
@@ -4366,8 +4351,7 @@ function describeNoLabelsGiven(error, clearFlag) {
4366
4351
  function describeAttachmentExists(error, forceFlag) {
4367
4352
  return `"${error.filePath}" already exists -- pass ${forceFlag} to overwrite it.`;
4368
4353
  }
4369
- //#endregion
4370
- //#region ../forgejo/src/issue-run.ts
4354
+ // ../forgejo/src/issue-run.ts
4371
4355
  var NothingToUpdateError = class extends FatalError {
4372
4356
  constructor() {
4373
4357
  super("Nothing to change: neither a title nor a body was given.");
@@ -4623,8 +4607,7 @@ function formatIssueList(result) {
4623
4607
  }
4624
4608
  return lines.join("\n");
4625
4609
  }
4626
- //#endregion
4627
- //#region src/issue-transport.ts
4610
+ // src/issue-transport.ts
4628
4611
  function githubRefusal(command) {
4629
4612
  return `bst-fj is Forgejo-only -- use \`gh\` or \`pnpm exec bst ${command}\` for a github.com repository.`;
4630
4613
  }
@@ -4647,8 +4630,7 @@ function forgejoIssueTransport(cwd, target, command) {
4647
4630
  target: resolved.target
4648
4631
  };
4649
4632
  }
4650
- //#endregion
4651
- //#region src/commands/issue-comment.ts
4633
+ // src/commands/issue-comment.ts
4652
4634
  const issueCommentCommand = defineCommand({
4653
4635
  meta: {
4654
4636
  name: "issue:comment",
@@ -4706,8 +4688,7 @@ const issueCommentCommand = defineCommand({
4706
4688
  }
4707
4689
  }
4708
4690
  });
4709
- //#endregion
4710
- //#region src/commands/issue-create.ts
4691
+ // src/commands/issue-create.ts
4711
4692
  const issueCreateCommand = defineCommand({
4712
4693
  meta: {
4713
4694
  name: "issue:create",
@@ -4780,8 +4761,7 @@ const issueCreateCommand = defineCommand({
4780
4761
  }
4781
4762
  }
4782
4763
  });
4783
- //#endregion
4784
- //#region ../forgejo/src/issue-run-download.ts
4764
+ // ../forgejo/src/issue-run-download.ts
4785
4765
  function isReadableFile(filePath) {
4786
4766
  try {
4787
4767
  readFileSync(filePath);
@@ -4874,8 +4854,7 @@ function formatDownload(result, dryRun) {
4874
4854
  for (const file of result.files) lines.push(` ${file.name} (${String(file.size)} bytes)`);
4875
4855
  return lines.join("\n");
4876
4856
  }
4877
- //#endregion
4878
- //#region src/commands/issue-download.ts
4857
+ // src/commands/issue-download.ts
4879
4858
  const issueDownloadCommand = defineCommand({
4880
4859
  meta: {
4881
4860
  name: "issue:download",
@@ -4934,8 +4913,7 @@ const issueDownloadCommand = defineCommand({
4934
4913
  }
4935
4914
  }
4936
4915
  });
4937
- //#endregion
4938
- //#region ../forgejo/src/issue-labels.ts
4916
+ // ../forgejo/src/issue-labels.ts
4939
4917
  const TimelineEntrySchema = z.object({
4940
4918
  id: z.number(),
4941
4919
  type: z.string(),
@@ -4986,8 +4964,7 @@ async function replaceForgejoIssueLabels(executor, conn, number, labelIds) {
4986
4964
  resource: `#${String(number)}`
4987
4965
  }, issueNotFoundMessage(conn, number));
4988
4966
  }
4989
- //#endregion
4990
- //#region ../forgejo/src/issue-run-labels.ts
4967
+ // ../forgejo/src/issue-run-labels.ts
4991
4968
  async function labelIssue(resolve, request) {
4992
4969
  const ref = parseIssueRef(request.ref);
4993
4970
  const number = requireIssueNumber(ref);
@@ -5056,8 +5033,7 @@ function formatIssueSetLabels(result, dryRun) {
5056
5033
  if (result.added.length > 0) lines.push(` ${dryRun ? "would add" : "added"}: ${result.added.join(", ")}`);
5057
5034
  return lines.join("\n");
5058
5035
  }
5059
- //#endregion
5060
- //#region src/commands/issue-label.ts
5036
+ // src/commands/issue-label.ts
5061
5037
  function defineIssueLabelCommand(action) {
5062
5038
  const name = action === "add" ? "issue:label" : "issue:unlabel";
5063
5039
  return defineCommand({
@@ -5116,8 +5092,7 @@ function defineIssueLabelCommand(action) {
5116
5092
  }
5117
5093
  const issueLabelCommand = defineIssueLabelCommand("add");
5118
5094
  const issueUnlabelCommand = defineIssueLabelCommand("remove");
5119
- //#endregion
5120
- //#region src/commands/issue-set-labels.ts
5095
+ // src/commands/issue-set-labels.ts
5121
5096
  const issueSetLabelsCommand = defineCommand({
5122
5097
  meta: {
5123
5098
  name: "issue:set-labels",
@@ -5177,8 +5152,7 @@ const issueSetLabelsCommand = defineCommand({
5177
5152
  }
5178
5153
  }
5179
5154
  });
5180
- //#endregion
5181
- //#region ../forgejo/src/issue-run-state.ts
5155
+ // ../forgejo/src/issue-run-state.ts
5182
5156
  var EmptyCommentError = class extends FatalError {
5183
5157
  constructor() {
5184
5158
  super("The comment resolved to empty text.");
@@ -5274,8 +5248,7 @@ function formatIssueState(result, dryRun) {
5274
5248
  }
5275
5249
  return lines.join("\n");
5276
5250
  }
5277
- //#endregion
5278
- //#region src/commands/issue-state.ts
5251
+ // src/commands/issue-state.ts
5279
5252
  function defineIssueStateCommand(action) {
5280
5253
  const name = action === "close" ? "issue:close" : "issue:reopen";
5281
5254
  return defineCommand({
@@ -5351,8 +5324,7 @@ function defineIssueStateCommand(action) {
5351
5324
  }
5352
5325
  const issueCloseCommand = defineIssueStateCommand("close");
5353
5326
  const issueReopenCommand = defineIssueStateCommand("reopen");
5354
- //#endregion
5355
- //#region src/commands/issue-list.ts
5327
+ // src/commands/issue-list.ts
5356
5328
  const issueListCommand = defineCommand({
5357
5329
  meta: {
5358
5330
  name: "issue:list",
@@ -5410,8 +5382,7 @@ const issueListCommand = defineCommand({
5410
5382
  }
5411
5383
  }
5412
5384
  });
5413
- //#endregion
5414
- //#region src/commands/issue-update.ts
5385
+ // src/commands/issue-update.ts
5415
5386
  const issueUpdateCommand = defineCommand({
5416
5387
  meta: {
5417
5388
  name: "issue:update",
@@ -5482,8 +5453,7 @@ const issueUpdateCommand = defineCommand({
5482
5453
  }
5483
5454
  }
5484
5455
  });
5485
- //#endregion
5486
- //#region src/registry-issue.ts
5456
+ // src/registry-issue.ts
5487
5457
  const issueSubCommands = {
5488
5458
  "issue:view": defineCommand({
5489
5459
  meta: {
@@ -5536,8 +5506,7 @@ const issueSubCommands = {
5536
5506
  "issue:set-labels": issueSetLabelsCommand,
5537
5507
  "issue:download": issueDownloadCommand
5538
5508
  };
5539
- //#endregion
5540
- //#region src/pr-checks.ts
5509
+ // src/pr-checks.ts
5541
5510
  async function resolvePrChecksTarget(fetcher, options) {
5542
5511
  const ref = parseIssueRef(options.pr);
5543
5512
  if (options.repo !== void 0 && ref.number === void 0 && options.branch === void 0) throw new FatalError("--repo requires --pr or --branch -- the current branch of this checkout means nothing in another repository, and inferring it there would silently answer about the wrong PR.");
@@ -5711,8 +5680,7 @@ function renderPrChecks(report) {
5711
5680
  lines.push(summaryParts.join(" -- "));
5712
5681
  return lines.join("\n");
5713
5682
  }
5714
- //#endregion
5715
- //#region src/commands/pr-checks.ts
5683
+ // src/commands/pr-checks.ts
5716
5684
  const prChecksCommand = defineCommand({
5717
5685
  meta: {
5718
5686
  name: "pr:checks",
@@ -5776,8 +5744,7 @@ const prChecksCommand = defineCommand({
5776
5744
  process.exitCode = report.status === "green" ? 0 : 1;
5777
5745
  }
5778
5746
  });
5779
- //#endregion
5780
- //#region ../forgejo/src/pr-close.ts
5747
+ // ../forgejo/src/pr-close.ts
5781
5748
  async function closePullRequest(api, request) {
5782
5749
  rejectEmptyComment(request.comment);
5783
5750
  return changeState(api, request.number, {
@@ -5794,15 +5761,13 @@ function formatPrClose(result, dryRun) {
5794
5761
  return lines.join("\n");
5795
5762
  }
5796
5763
  const PR_CLOSE_JSON_HELP = "Emit one JSON document: number, url, action (close), state ({previous, current}), changed, merged? (present only when the pull request was already closed), comment? ({posted}; present only when a comment was given).";
5797
- //#endregion
5798
- //#region ../forgejo/src/pr-number.ts
5764
+ // ../forgejo/src/pr-number.ts
5799
5765
  function parsePrNumber(raw) {
5800
5766
  const value = Number(raw);
5801
5767
  if (!/^\d+$/.test(raw) || !Number.isSafeInteger(value) || value < 1) throw new FatalError(`Invalid pull request number "${raw}" (expected a positive integer).`);
5802
5768
  return value;
5803
5769
  }
5804
- //#endregion
5805
- //#region src/commands/pr-close.ts
5770
+ // src/commands/pr-close.ts
5806
5771
  const prCloseCommand = defineCommand({
5807
5772
  meta: {
5808
5773
  name: "pr:close",
@@ -5866,39 +5831,7 @@ const prCloseCommand = defineCommand({
5866
5831
  }
5867
5832
  }
5868
5833
  });
5869
- //#endregion
5870
- //#region ../forgejo/src/closing-refs.ts
5871
- const CLOSING_REF = /(?:^|[\s([])(clos(?:e|es|ed)|fix(?:es|ed)?|resolv(?:e|es|ed))(?::[ \t]*|[ \t]+)((?:[\w.-]+\/[\w.-]+)?#\d+)(?![\w-])/gim;
5872
- function capitalize(word) {
5873
- return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
5874
- }
5875
- function extractClosingRefs(messages) {
5876
- const byIssue = /* @__PURE__ */ new Map();
5877
- for (const message of messages) for (const [, keyword, issue] of message.matchAll(CLOSING_REF)) {
5878
- if (keyword === void 0 || issue === void 0) continue;
5879
- const key = issue.toLowerCase();
5880
- if (!byIssue.has(key)) byIssue.set(key, {
5881
- text: `${capitalize(keyword)} ${issue}`,
5882
- issue
5883
- });
5884
- }
5885
- return [...byIssue.values()];
5886
- }
5887
- function closedIssues(text) {
5888
- return new Set(extractClosingRefs([text]).map((ref) => ref.issue.toLowerCase()));
5889
- }
5890
- function droppedClosingRefs(messages, body) {
5891
- const closed = closedIssues(body);
5892
- return extractClosingRefs(messages).filter((ref) => !closed.has(ref.issue.toLowerCase()));
5893
- }
5894
- function carryForwardClosingRefs(source, target) {
5895
- const missing = droppedClosingRefs([source], target);
5896
- if (missing.length === 0) return target;
5897
- const refLines = missing.map((ref) => ref.text).join("\n");
5898
- return target.trim() === "" ? refLines : `${target}\n\n${refLines}`;
5899
- }
5900
- //#endregion
5901
- //#region ../forgejo/src/git.ts
5834
+ // ../forgejo/src/git.ts
5902
5835
  const GIT_LOCAL_TIMEOUT_MS = 6e4;
5903
5836
  const GIT_WRITE_TIMEOUT_MS = 3e5;
5904
5837
  function pickDefaultBranch(override, originHead) {
@@ -6009,8 +5942,7 @@ async function pushBranch(git, cwd, branch, env, forceWithLease = false) {
6009
5942
  });
6010
5943
  if (result.exitCode !== 0) throw new FatalError(`Failed to push ${branch}: ${result.stderr || result.stdout}`);
6011
5944
  }
6012
- //#endregion
6013
- //#region ../forgejo/src/pr-upsert.ts
5945
+ // ../forgejo/src/pr-upsert.ts
6014
5946
  const COMMIT_TYPES = /* @__PURE__ */ new Set([
6015
5947
  "feat",
6016
5948
  "fix",
@@ -6218,8 +6150,7 @@ async function runPrUpsert(git, host, options) {
6218
6150
  ...shape
6219
6151
  };
6220
6152
  }
6221
- //#endregion
6222
- //#region ../forgejo/src/pr-upsert-messages.ts
6153
+ // ../forgejo/src/pr-upsert-messages.ts
6223
6154
  function describePrModeError(error, commands) {
6224
6155
  if (error.reason === "already-open") {
6225
6156
  const createVerb = commands.create.split(" ").at(-1) ?? commands.create;
@@ -6298,8 +6229,7 @@ function formatPrUpdate(result, rewrites, flags) {
6298
6229
  body: null
6299
6230
  };
6300
6231
  }
6301
- //#endregion
6302
- //#region ../forgejo/src/pr-host.ts
6232
+ // ../forgejo/src/pr-host.ts
6303
6233
  function forgejoPrHost(fetcher, conn) {
6304
6234
  return {
6305
6235
  wipTitles: true,
@@ -6332,8 +6262,7 @@ function forgejoPrEditHost(fetcher, conn) {
6332
6262
  ready: (number, write) => updatePr(fetcher, conn, number, { title: write.title })
6333
6263
  };
6334
6264
  }
6335
- //#endregion
6336
- //#region src/git.ts
6265
+ // src/git.ts
6337
6266
  const TIMED_OUT_EXIT_CODE = 124;
6338
6267
  const ABORTED_EXIT_CODE = 143;
6339
6268
  function cliGit() {
@@ -6409,8 +6338,7 @@ function cliGit() {
6409
6338
  });
6410
6339
  }) };
6411
6340
  }
6412
- //#endregion
6413
- //#region src/pr-run.ts
6341
+ // src/pr-run.ts
6414
6342
  const COMMANDS = {
6415
6343
  create: "pnpm exec bst-fj pr:create",
6416
6344
  update: "pnpm exec bst-fj pr:update"
@@ -6444,8 +6372,7 @@ async function runForgejoPr(githubRefusal, options) {
6444
6372
  });
6445
6373
  }
6446
6374
  }
6447
- //#endregion
6448
- //#region src/commands/pr-create.ts
6375
+ // src/commands/pr-create.ts
6449
6376
  const prCreateCommand = defineCommand({
6450
6377
  meta: {
6451
6378
  name: "pr:create",
@@ -6486,7 +6413,7 @@ const prCreateCommand = defineCommand({
6486
6413
  },
6487
6414
  json: {
6488
6415
  type: "boolean",
6489
- description: "Emit one JSON document: action (created | updated | would-create | would-update), number (or null), url (or null), branch, base, title, body, droppedRefs? ([{text, issue}]), dryRun. A create or would-create carries droppedRefs; on a dry run, number and url are null."
6416
+ description: "Emit one JSON document: action (created | updated | would-create | would-update), number (or null), url (or null), branch, base, title, body, droppedRefs? ([{text, issue}]), dryRun. A create or would-create carries droppedRefs; on a dry run, number and url are null. The document carries no claims member and no claim advice line: the closed-issue claim check reads the repo's .tooling.json and is bst pr:create's alone."
6490
6417
  },
6491
6418
  verbose: {
6492
6419
  type: "boolean",
@@ -6514,8 +6441,7 @@ const prCreateCommand = defineCommand({
6514
6441
  if (summary.body !== null) out.text(`${summary.body.heading}\n${summary.body.text}`);
6515
6442
  }
6516
6443
  });
6517
- //#endregion
6518
- //#region ../forgejo/src/pr-files.ts
6444
+ // ../forgejo/src/pr-files.ts
6519
6445
  const DEFAULT_LIMIT = 100;
6520
6446
  const PrFileEntrySchema = z.object({
6521
6447
  filename: z.string(),
@@ -6560,8 +6486,7 @@ async function readPrFilesPage(executor, conn, prNumber, page, limit) {
6560
6486
  truncated: res.headers.get("x-hasmore") === "true"
6561
6487
  };
6562
6488
  }
6563
- //#endregion
6564
- //#region src/pr-files.ts
6489
+ // src/pr-files.ts
6565
6490
  function runPrFiles(fetcher, options) {
6566
6491
  const number = parsePrNumber(options.number);
6567
6492
  return listAllPrFiles(fetcher, requireForgejoTarget(options.cwd, parseRepoTarget(options.repo), "pr:files is Forgejo-only -- gh pr diff --name-only already serves GitHub."), number);
@@ -6572,8 +6497,7 @@ function renderPrFiles(listing) {
6572
6497
  if (listing.truncated) lines.push("Listing truncated; the pull request changes more files.");
6573
6498
  return lines.join("\n");
6574
6499
  }
6575
- //#endregion
6576
- //#region src/commands/pr-files.ts
6500
+ // src/commands/pr-files.ts
6577
6501
  const prFilesCommand = defineCommand({
6578
6502
  meta: {
6579
6503
  name: "pr:files",
@@ -6612,8 +6536,7 @@ const prFilesCommand = defineCommand({
6612
6536
  out.text(renderPrFiles(listing));
6613
6537
  }
6614
6538
  });
6615
- //#endregion
6616
- //#region src/pr-list.ts
6539
+ // src/pr-list.ts
6617
6540
  function parseState(state) {
6618
6541
  if (state === "open" || state === "closed" || state === "all") return state;
6619
6542
  throw new FatalError(`Invalid --state "${state}" (expected open, closed, or all).`);
@@ -6650,8 +6573,7 @@ function renderPrList(result) {
6650
6573
  return `#${String(pr.number)} ${statusLabel(pr)} ${branches}: ${pr.title ?? "(no title)"}${labels}${url}`;
6651
6574
  }).join("\n");
6652
6575
  }
6653
- //#endregion
6654
- //#region src/commands/pr-list.ts
6576
+ // src/commands/pr-list.ts
6655
6577
  const prListCommand = defineCommand({
6656
6578
  meta: {
6657
6579
  name: "pr:list",
@@ -6694,8 +6616,7 @@ const prListCommand = defineCommand({
6694
6616
  out.text(renderPrList(result));
6695
6617
  }
6696
6618
  });
6697
- //#endregion
6698
- //#region ../forgejo/src/pr-merge.ts
6619
+ // ../forgejo/src/pr-merge.ts
6699
6620
  async function mergePr(executor, conn, prNumber, options) {
6700
6621
  const url = `${conn.serverUrl}/api/v1/repos/${conn.repository}/pulls/${String(prNumber)}/merge`;
6701
6622
  const body = {
@@ -6798,8 +6719,7 @@ z.object({
6798
6719
  sha: z.string()
6799
6720
  })
6800
6721
  });
6801
- //#endregion
6802
- //#region ../forgejo/src/pr-merge-run.ts
6722
+ // ../forgejo/src/pr-merge-run.ts
6803
6723
  const MERGE_METHODS = [
6804
6724
  "merge",
6805
6725
  "rebase",
@@ -6870,8 +6790,7 @@ async function runPrMergeCore(fetcher, conn, number, options = {}) {
6870
6790
  }
6871
6791
  };
6872
6792
  }
6873
- //#endregion
6874
- //#region src/pr-merge.ts
6793
+ // src/pr-merge.ts
6875
6794
  function parseMethod(raw) {
6876
6795
  if (raw === void 0) return "merge";
6877
6796
  const method = MERGE_METHODS.find((candidate) => candidate === raw);
@@ -6898,8 +6817,7 @@ function renderPrMerge(result) {
6898
6817
  const what = `PR #${String(result.number)} (${result.method}) at ${result.headSha.slice(0, 12)}, checks ${result.checks}`;
6899
6818
  return result.merged ? `Merged ${what}.` : `Dry run: would merge ${what}.`;
6900
6819
  }
6901
- //#endregion
6902
- //#region src/commands/pr-merge.ts
6820
+ // src/commands/pr-merge.ts
6903
6821
  const prMergeCommand = defineCommand({
6904
6822
  meta: {
6905
6823
  name: "pr:merge",
@@ -6955,8 +6873,7 @@ const prMergeCommand = defineCommand({
6955
6873
  out.text(renderPrMerge(result));
6956
6874
  }
6957
6875
  });
6958
- //#endregion
6959
- //#region ../forgejo/src/pr-edit.ts
6876
+ // ../forgejo/src/pr-edit.ts
6960
6877
  const MERGEABLE_RECHECK_DELAY_MS = 2e3;
6961
6878
  function isOpen(live) {
6962
6879
  return live.state === "open" && live.merged === false;
@@ -7083,8 +7000,7 @@ function renderPrReady(result) {
7083
7000
  if (result.action === "would-ready") return `Dry run: pull request ${number} would stop being a draft, reading "${result.title}".`;
7084
7001
  return `Dry run: pull request ${number} would read "${result.title}".`;
7085
7002
  }
7086
- //#endregion
7087
- //#region src/registry-pr.ts
7003
+ // src/registry-pr.ts
7088
7004
  const prSubCommands = {
7089
7005
  "pr:checks": prChecksCommand,
7090
7006
  "pr:close": prCloseCommand,
@@ -7249,8 +7165,7 @@ const prSubCommands = {
7249
7165
  }
7250
7166
  })
7251
7167
  };
7252
- //#endregion
7253
- //#region src/registry.ts
7168
+ // src/registry.ts
7254
7169
  const bstFjSubCommands = {
7255
7170
  "commit:status": commitStatusCommand,
7256
7171
  labels: labelsCommand,
@@ -7262,8 +7177,7 @@ const bstFjSubCommands = {
7262
7177
  webhooks: webhooksCommand,
7263
7178
  ...issueSubCommands
7264
7179
  };
7265
- //#endregion
7266
- //#region src/bin.ts
7180
+ // src/bin.ts
7267
7181
  applyVerbosityFromArgs(process.argv.slice(2));
7268
7182
  rootLogger.debug(describeEnvFileLoad(envFileLoad));
7269
7183
  setForgejoLogger(rootLogger);
@@ -7275,5 +7189,4 @@ await runCli({
7275
7189
  subCommands: bstFjSubCommands,
7276
7190
  describeError: describeForgeError
7277
7191
  });
7278
- //#endregion
7279
7192
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bensandee/forgejo-cli",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "bst-fj: Forgejo API commands without the rest of bst",
5
5
  "license": "MIT",
6
6
  "repository": {