@coderook/cli 0.39.0 → 0.40.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.
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.REGISTRY = void 0;
7
8
  /**
8
9
  * cbx — the CodeBox engine from the command line, talking to CodeRook.
9
10
  *
@@ -40,6 +41,7 @@ const issue_command_js_1 = require("./issue_command.js");
40
41
  const verify_command_js_1 = require("./verify_command.js");
41
42
  const community_command_js_1 = require("./community_command.js");
42
43
  const pr_command_js_1 = require("./pr_command.js");
44
+ const settings_commands_js_1 = require("./settings_commands.js");
43
45
  const project_commands_js_1 = require("./project_commands.js");
44
46
  const track_commands_js_1 = require("./track_commands.js");
45
47
  const tracks_js_1 = require("../../cbx/src/core/tracks.js");
@@ -722,7 +724,7 @@ async function commandImport(parsed) {
722
724
  flags: submitFlags,
723
725
  });
724
726
  if (code === 0 && plan.temporary) {
725
- console.log(dim(`The working copy stays at ${plan.folder} until you remove it.
727
+ console.log(dim(`The working copy stays at ${plan.folder} until you remove it.
726
728
  ` +
727
729
  `Run ${accent("cbx get " + plan.name)} anywhere to fetch it fresh.`));
728
730
  }
@@ -1008,17 +1010,17 @@ async function commandSubmit(parsed) {
1008
1010
  */
1009
1011
  const shielded = (await (0, worktree_js_1.detectPrivateDirectories)(folder)).filter((finding) => [...sending].some((file) => file === finding.path || file.startsWith(`${finding.path}/`)));
1010
1012
  if (shielded.length && !hasFlag(parsed, "allow-private")) {
1011
- console.log(red(`
1013
+ console.log(red(`
1012
1014
  ${shielded.length} folder${shielded.length === 1 ? "" : "s"} here belong${shielded.length === 1 ? "s" : ""} to a program, not to your project:`));
1013
1015
  for (const finding of shielded) {
1014
1016
  console.log(` ${finding.path} ${dim(`— ${finding.because}`)}`);
1015
1017
  }
1016
- console.log(`
1018
+ console.log(`
1017
1019
  Nothing was sent. To leave them behind:`);
1018
1020
  for (const finding of shielded) {
1019
1021
  console.log(` ${accent(`echo "${finding.rule}" >> .gitignore`)}`);
1020
1022
  }
1021
- console.error(`
1023
+ console.error(`
1022
1024
  Or pass ${accent("--allow-private")} if they genuinely belong in the project.`);
1023
1025
  return 1;
1024
1026
  }
@@ -1067,7 +1069,7 @@ Or pass ${accent("--allow-private")} if they genuinely belong in the project.`);
1067
1069
  `rest were not opened.`));
1068
1070
  }
1069
1071
  if (stillPasted.length) {
1070
- console.log(red(`
1072
+ console.log(red(`
1071
1073
  ${stillPasted.length} file${stillPasted.length === 1 ? " has a credential" : "s have credentials"} inside:`));
1072
1074
  for (const finding of stillPasted.slice(0, 20)) {
1073
1075
  console.log(` ${finding.path}`);
@@ -1082,11 +1084,11 @@ ${stillPasted.length} file${stillPasted.length === 1 ? " has a credential" : "s
1082
1084
  console.log(dim(` …and ${stillPasted.length - 20} more`));
1083
1085
  }
1084
1086
  if (!hasFlag(parsed, "allow-secrets")) {
1085
- console.error(`
1087
+ console.error(`
1086
1088
  Nothing was sent. Move the key into an environment variable, and if` +
1087
1089
  ` it has ever been published, replace it at the service that issued` +
1088
1090
  ` it — a key that has leaked stays leaked.` +
1089
- `
1091
+ `
1090
1092
  Pass ${accent("--allow-secrets")} if these are not real keys.`);
1091
1093
  return 1;
1092
1094
  }
@@ -1292,7 +1294,7 @@ Pass ${accent("--allow-secrets")} if these are not real keys.`);
1292
1294
  continue;
1293
1295
  }
1294
1296
  if (failure?.kind === "interrupted") {
1295
- console.error(red(`
1297
+ console.error(red(`
1296
1298
  The connection failed: ${text}`));
1297
1299
  console.error(`Your work may already have been saved. Run the same command again —` +
1298
1300
  ` it will not create a second version.`);
@@ -1535,7 +1537,7 @@ async function commandGet(parsed) {
1535
1537
  `changed while the interrupted fetch was stopped:`));
1536
1538
  for (const file of changedInTheGap.slice(0, 20))
1537
1539
  console.error(` ${file.path}`);
1538
- console.error(`
1540
+ console.error(`
1539
1541
  Save them with ${accent("cbx submit")}, or finish the fetch and ` +
1540
1542
  `discard them with ${accent("cbx get --replace")}.`);
1541
1543
  return 1;
@@ -1818,8 +1820,8 @@ async function suggestRules(folder, apply) {
1818
1820
  const addition = (0, detect_js_1.rulesFromSuggestions)(recommended);
1819
1821
  const shared = rules.shared.trimEnd();
1820
1822
  await (0, worktree_js_1.writeRules)(folder, {
1821
- shared: shared ? `${shared}
1822
-
1823
+ shared: shared ? `${shared}
1824
+
1823
1825
  ${addition}` : addition,
1824
1826
  local: rules.local,
1825
1827
  });
@@ -2024,7 +2026,7 @@ async function commandMerges(parsed) {
2024
2026
  const counts = merge.conflicts;
2025
2027
  console.log(`${accent(merge.reference)} ${counts ? `${counts.unresolved} of ${counts.total} still to decide` : ""} ${dim(new Date(merge.createdAt).toLocaleString())}`);
2026
2028
  }
2027
- console.log(dim(`
2029
+ console.log(dim(`
2028
2030
  Run cbx merge <reference> to look at one.`));
2029
2031
  return 0;
2030
2032
  }
@@ -2127,7 +2129,7 @@ async function commandMerge(parsed) {
2127
2129
  console.log(dim(` waiting on ${waiting.map((person) => person.displayName).join(", ")}`));
2128
2130
  }
2129
2131
  }
2130
- console.log(`
2132
+ console.log(`
2131
2133
  ${accent(now.mergeTrack.reference)} · ` +
2132
2134
  /*
2133
2135
  The combined version is only counted once it can be built; until then
@@ -2146,7 +2148,7 @@ ${accent(now.mergeTrack.reference)} · ` +
2146
2148
  return 1;
2147
2149
  }
2148
2150
  const applied = await (0, api_js_1.applyMerge)(summary.id);
2149
- console.log(`
2151
+ console.log(`
2150
2152
  Applied as ${accent(`v${applied.version.sequence}`)}.`);
2151
2153
  if (applied.closedIssues?.length) {
2152
2154
  console.log(`Closed ${applied.closedIssues.map((number) => `#${number}`).join(", ")}.`);
@@ -2156,13 +2158,13 @@ Applied as ${accent(`v${applied.version.sequence}`)}.`);
2156
2158
  }
2157
2159
  const stillOpen = now.conflicts.some((conflict) => !conflict.resolvedAt);
2158
2160
  if (!decision && stillOpen) {
2159
- console.log(dim(`
2161
+ console.log(dim(`
2160
2162
  --mine keeps yours, --theirs keeps what was already saved,` +
2161
- ` --both keeps theirs and saves yours beside it, --drop removes the file.
2163
+ ` --both keeps theirs and saves yours beside it, --drop removes the file.
2162
2164
  Add --path <file> for one file, then --apply when ready.`));
2163
2165
  }
2164
2166
  else if (now.provisional.ready) {
2165
- console.log(dim(`
2167
+ console.log(dim(`
2166
2168
  Run cbx merge ${now.mergeTrack.reference} --apply to publish it.`));
2167
2169
  }
2168
2170
  return 0;
@@ -2320,7 +2322,7 @@ const SPECS = [
2320
2322
  },
2321
2323
  {
2322
2324
  name: "status",
2323
- group: "Working with a folder",
2325
+ group: "Saving work",
2324
2326
  summary: "what is here that is not saved yet",
2325
2327
  usage: "status [folder]",
2326
2328
  detail: "Compares the folder against the last version you sent and lists what\n" +
@@ -2332,7 +2334,7 @@ const SPECS = [
2332
2334
  {
2333
2335
  name: "submit",
2334
2336
  aliases: ["publish"],
2335
- group: "Working with a folder",
2337
+ group: "Saving work",
2336
2338
  summary: "send the changes as a new save",
2337
2339
  usage: 'submit [folder] -m "…"',
2338
2340
  detail: "Sends everything that changed since the last save. If the folder is\n" +
@@ -2386,7 +2388,7 @@ const SPECS = [
2386
2388
  {
2387
2389
  name: "diff",
2388
2390
  aliases: ["changes"],
2389
- group: "Working with a folder",
2391
+ group: "Saving work",
2390
2392
  summary: "what changed, line by line",
2391
2393
  usage: "diff [from] [to]",
2392
2394
  detail: "With nothing after it, compares this folder against the version it is\n" +
@@ -2463,6 +2465,7 @@ const SPECS = [
2463
2465
  group: "History on this machine",
2464
2466
  summary: "put files back the way a save had them",
2465
2467
  usage: "restore [paths…] [--from <save>]",
2468
+ brief: "restore [paths…]",
2466
2469
  detail: "With no paths, makes the whole folder match the save; with paths,\n" +
2467
2470
  "only those files and folders. The default is the last save, which\n" +
2468
2471
  "throws away what you changed since.\n\n" +
@@ -2497,7 +2500,7 @@ const SPECS = [
2497
2500
  },
2498
2501
  {
2499
2502
  name: "link",
2500
- group: "Working with a folder",
2503
+ group: "Getting started",
2501
2504
  summary: "connect this folder to a project already on your account",
2502
2505
  usage: "link <project> [folder]",
2503
2506
  detail: "Says which project this folder is a copy of, without sending or\n" +
@@ -2511,7 +2514,7 @@ const SPECS = [
2511
2514
  },
2512
2515
  {
2513
2516
  name: "unlink",
2514
- group: "Working with a folder",
2517
+ group: "Getting started",
2515
2518
  summary: "detach this folder from its project",
2516
2519
  usage: "unlink [folder]",
2517
2520
  detail: "Forgets which project this folder belongs to. Nothing is deleted:\n" +
@@ -2600,7 +2603,7 @@ const SPECS = [
2600
2603
  */
2601
2604
  name: "track",
2602
2605
  aliases: ["checkout"],
2603
- group: "Working with a folder",
2606
+ group: "Saving work",
2604
2607
  summary: "show or change the line this folder saves to",
2605
2608
  usage: "track [name]",
2606
2609
  detail: "With no name, prints the line this folder saves to. With one, switches\n" +
@@ -2621,7 +2624,7 @@ const SPECS = [
2621
2624
  {
2622
2625
  name: "tracks",
2623
2626
  aliases: ["branch", "branches"],
2624
- group: "Your projects",
2627
+ group: "Lines, merges and pull requests",
2625
2628
  summary: "the lines a project has, and any waiting on a decision",
2626
2629
  usage: "tracks [project]",
2627
2630
  detail: "Lists every line on the project, marking the one this folder saves to.\n" +
@@ -2633,7 +2636,7 @@ const SPECS = [
2633
2636
  },
2634
2637
  {
2635
2638
  name: "get",
2636
- group: "Working with a folder",
2639
+ group: "Saving work",
2637
2640
  summary: "bring this folder up to date",
2638
2641
  usage: "get [folder]",
2639
2642
  options: [
@@ -2643,7 +2646,7 @@ const SPECS = [
2643
2646
  },
2644
2647
  {
2645
2648
  name: "clone",
2646
- group: "Working with a folder",
2649
+ group: "Getting started",
2647
2650
  summary: "fetch a project into a new folder",
2648
2651
  usage: "clone <project> [dir]",
2649
2652
  options: [
@@ -2658,7 +2661,7 @@ const SPECS = [
2658
2661
  {
2659
2662
  name: "licence",
2660
2663
  aliases: ["license"],
2661
- group: "Working with a folder",
2664
+ group: "Saving work",
2662
2665
  summary: "choose a licence, so people may actually use your work",
2663
2666
  usage: "licence [name] [folder]",
2664
2667
  detail: "A project with no licence cannot be used by anybody, whatever else it\n" +
@@ -2688,7 +2691,7 @@ const SPECS = [
2688
2691
  {
2689
2692
  name: "ignore",
2690
2693
  aliases: ["rules"],
2691
- group: "Working with a folder",
2694
+ group: "Saving work",
2692
2695
  summary: "show the ignore rules for this folder",
2693
2696
  usage: "ignore [folder]",
2694
2697
  detail: "The local list of things not to send — build output, dependencies,\n" +
@@ -2722,14 +2725,14 @@ const SPECS = [
2722
2725
  },
2723
2726
  {
2724
2727
  name: "projects",
2725
- group: "Your projects",
2728
+ group: "Getting started",
2726
2729
  summary: "every project on your account",
2727
2730
  usage: "projects",
2728
2731
  run: () => commandProjects(),
2729
2732
  },
2730
2733
  {
2731
2734
  name: "versions",
2732
- group: "Your projects",
2735
+ group: "Versions and releases",
2733
2736
  summary: "what has been saved to a project",
2734
2737
  usage: "versions [project]",
2735
2738
  detail: "Newest first. Run it inside a linked folder to leave the name out.\n\n" +
@@ -2750,9 +2753,10 @@ const SPECS = [
2750
2753
  },
2751
2754
  {
2752
2755
  name: "workspace",
2753
- group: "Your projects",
2756
+ group: "Workspaces",
2754
2757
  summary: "edit, save and run a private project remotely without a checkout",
2755
2758
  usage: "workspace <open|list|show|read|files|search|diff|patch|save|run|logs|cancel|deploy|preview|handoff|close|recipe|assign|assignments|unassign|checkout> <project> [workspace] [job] | workspace push [folder]",
2759
+ brief: "workspace <action> <project>",
2756
2760
  detail: "Works on CodeRook's durable remote draft, never the current local folder. Use --data-file for structured edits or recipe configuration. Mutations need the reviewed --revision and a unique --key; reuse the same key and request when retrying. Recipes reference existing project workflows. Saving and deploying are separate operations.",
2757
2761
  options: [
2758
2762
  { flags: "--data-file <path>", description: "read an operation's JSON from this local file" },
@@ -2780,8 +2784,8 @@ const SPECS = [
2780
2784
  },
2781
2785
  {
2782
2786
  name: "machines",
2783
- group: "Your projects",
2784
- summary: "the PCs working on a project, how far behind each is, and its runners",
2787
+ group: "Actions and builds",
2788
+ summary: "the PCs on a project, how far behind each is, and its runners",
2785
2789
  usage: "machines [project]",
2786
2790
  detail: "Every PC with a folder linked to the project, or working on a draft handed to it, says which version it holds when cbx runs there. " +
2787
2791
  "This lists them with how many versions behind the project's line each is and how many files it has not saved, then the project's runners. " +
@@ -2791,26 +2795,20 @@ const SPECS = [
2791
2795
  },
2792
2796
  {
2793
2797
  name: "ai",
2794
- group: "Your projects",
2795
- summary: "what this project says about machines",
2796
- usage: "ai [project] [--read off]",
2797
- detail: "Shows the four answers a project gives about automated clients, and\n" +
2798
- "changes them. Everything is allowed until you say otherwise.\n\n" +
2798
+ group: "Project settings",
2799
+ summary: "what this project lets AI do (read only)",
2800
+ usage: "ai [project]",
2801
+ detail: "Shows the four answers a project gives about automated clients: can AI\n" +
2802
+ "read it, download it, contribute to it, and make requests to it.\n" +
2803
+ "Everything is allowed until somebody says otherwise.\n\n" +
2799
2804
  "Turning reading off is the one that refuses model training: it declares\n" +
2800
2805
  "the project as not-for-training in the page, in the response headers,\n" +
2801
- "and in the service's robots.txt. Turning downloads off does not — those\n" +
2802
- "are separate questions and answering one says nothing about the other.",
2803
- options: [
2804
- { flags: "--read [off]", description: "reading, indexing, summarising, training" },
2805
- { flags: "--download [off]", description: "taking the files" },
2806
- { flags: "--contribute [off]", description: "automated contributions" },
2807
- { flags: "--request [off]", description: "automated calls to its endpoints" },
2808
- ],
2809
- examples: [
2810
- "cbx ai my-project",
2811
- "cbx ai my-project --read off",
2812
- "cbx ai my-project --download off --request off",
2813
- ],
2806
+ "and in the service's robots.txt.\n\n" +
2807
+ "These are changed by a person, on the website (the project's Settings →\n" +
2808
+ "Access & AI) or in the desktop app, never from the command line. The\n" +
2809
+ "service refuses the change from any token, so an assistant holding one\n" +
2810
+ "cannot switch off the rule that keeps it out.",
2811
+ examples: ["cbx ai", "cbx ai my-project"],
2814
2812
  run: project_commands_js_1.commandAi,
2815
2813
  },
2816
2814
  {
@@ -2819,7 +2817,7 @@ const SPECS = [
2819
2817
  release. This is who can reach the project, and it is named for that.
2820
2818
  */
2821
2819
  name: "visibility",
2822
- group: "Your projects",
2820
+ group: "Project settings",
2823
2821
  summary: "who can reach a project: private, link only or public",
2824
2822
  usage: "visibility [level] [project]",
2825
2823
  detail: "The level is public, unlisted or private. With none, says what the\n" +
@@ -2842,9 +2840,158 @@ const SPECS = [
2842
2840
  ],
2843
2841
  run: project_commands_js_1.commandVisibility,
2844
2842
  },
2843
+ {
2844
+ /*
2845
+ Not `name` or `rename`, which read as acting on a file or a line. This
2846
+ is what the project says about itself: the website's Settings → General.
2847
+ */
2848
+ name: "about",
2849
+ group: "Project settings",
2850
+ summary: "a project's name, description and address",
2851
+ usage: "about [project] [--name <text>] [--description <text>]",
2852
+ brief: "about [project]",
2853
+ detail: "Shows the project's name, description, address and visibility, and\n" +
2854
+ "changes the name or the description. The address comes from the\n" +
2855
+ "project's short name, which stays as it is. An empty description\n" +
2856
+ "clears it.",
2857
+ options: [
2858
+ { flags: "--name <text>", description: "what the project is called" },
2859
+ { flags: "--description <text>", description: "one or two sentences about it" },
2860
+ { flags: "--project <name>", description: "a project other than this folder's" },
2861
+ ],
2862
+ examples: [
2863
+ "cbx about",
2864
+ 'cbx about --name "Night Owl Diner"',
2865
+ 'cbx about my-project --description "A diner sim set after midnight."',
2866
+ ],
2867
+ run: settings_commands_js_1.commandAbout,
2868
+ },
2869
+ {
2870
+ /*
2871
+ Beside `cbx tracks` rather than inside it. That lists where somebody can
2872
+ save and is read all day; these are the rules an owner sets once.
2873
+ */
2874
+ name: "line-rules",
2875
+ group: "Lines, merges and pull requests",
2876
+ summary: "protection, approvals and required checks on each line",
2877
+ usage: "line-rules [line] [--protect|--unprotect] [--approvals <n>] [--checks <a,b>] [--code-owners on|off] [--project <p>]",
2878
+ brief: "line-rules [line] [options]",
2879
+ detail: "With no line, lists every line with its rules and the code owners read\n" +
2880
+ "from the default line's CODEOWNERS file. Name a line to change it — the\n" +
2881
+ "website's Settings → Lines & reviews. Only the owner and admins can.\n\n" +
2882
+ "A protected line refuses restores and merges that would overwrite it.\n" +
2883
+ "Approvals is how many people must approve before a merge may land (0 to\n" +
2884
+ "10). Checks are the names that must pass, comma separated; none clears\n" +
2885
+ "them. Code owners on means a code owner of what changed must approve.",
2886
+ options: [
2887
+ { flags: "--protect", description: "protect the line" },
2888
+ { flags: "--unprotect", description: "stop protecting it" },
2889
+ { flags: "--approvals <n>", description: "approvals a merge needs, 0 to 10" },
2890
+ { flags: "--checks <a,b>", description: "checks that must pass; none for no checks" },
2891
+ { flags: "--code-owners <on|off>", description: "whether a code owner must approve" },
2892
+ { flags: "--project <name>", description: "a project other than this folder's" },
2893
+ ],
2894
+ examples: [
2895
+ "cbx line-rules",
2896
+ "cbx line-rules main --protect --approvals 1",
2897
+ "cbx line-rules main --checks build,test --code-owners on",
2898
+ "cbx line-rules release --unprotect --checks none",
2899
+ ],
2900
+ run: settings_commands_js_1.commandLineRules,
2901
+ },
2902
+ {
2903
+ name: "upload-rules",
2904
+ group: "Project settings",
2905
+ summary: "what uploads leave out, and encrypting secret files",
2906
+ usage: "upload-rules [--ignore <file>] [--keep <file>] [--encrypt on|off] [--warn-large <MiB>] [--hold-pushes on|off] [--project <p>]",
2907
+ brief: "upload-rules [options]",
2908
+ detail: "The project's upload rules — the website's Settings → Files & privacy →\n" +
2909
+ "Encrypted uploads. The desktop app and the website's scans read them.\n" +
2910
+ "Ignore rules leave files out; keep rules bring back what an ignore rule\n" +
2911
+ "caught. Both are read from a file of patterns, one per line, in the\n" +
2912
+ "shape of a .gitignore; none clears them. This folder's own ignore file\n" +
2913
+ "is `cbx ignore`.\n\n" +
2914
+ "--encrypt covers files recognised as secrets before they are stored.\n" +
2915
+ "--hold-pushes makes saves from anybody below admin wait for an admin to\n" +
2916
+ "accept them (see `cbx held`). Owners and admins change these.",
2917
+ options: [
2918
+ { flags: "--ignore <file>", description: "replace the ignore rules with this file's" },
2919
+ { flags: "--keep <file>", description: "replace the keep rules with this file's" },
2920
+ { flags: "--encrypt <on|off>", description: "encrypt files recognised as secrets" },
2921
+ { flags: "--warn-large <MiB>", description: "warn about files larger than this" },
2922
+ { flags: "--hold-pushes <on|off>", description: "saves below admin wait to be accepted" },
2923
+ { flags: "--project <name>", description: "a project other than this folder's" },
2924
+ ],
2925
+ examples: [
2926
+ "cbx upload-rules",
2927
+ "cbx upload-rules --ignore .coderookignore --warn-large 512",
2928
+ "cbx upload-rules --encrypt on --keep none",
2929
+ ],
2930
+ run: settings_commands_js_1.commandUploadRules,
2931
+ },
2932
+ {
2933
+ name: "assistant",
2934
+ group: "Project settings",
2935
+ summary: "the pull-request assistant: when it works and what it may do",
2936
+ usage: "assistant [manual|automated] [project] [--review on|off] [--describe on|off] [--suggest on|off] [--change on|off] [--approve on|off] [--merge on|off]",
2937
+ brief: "assistant [manual|automated]",
2938
+ detail: "Manual means it works only when somebody asks on a pull request.\n" +
2939
+ "Automated means it works on its own, doing what is switched on:\n" +
2940
+ "reviewing, describing, suggesting, changing, approving and merging.\n" +
2941
+ "Merging needs approving on too. Automated comes with a subscription on\n" +
2942
+ "the owner's account. Only the project's admins change it — the\n" +
2943
+ "website's Settings → Automation.",
2944
+ options: [
2945
+ { flags: "--review <on|off>", description: "review each pull request" },
2946
+ { flags: "--describe <on|off>", description: "write the description" },
2947
+ { flags: "--suggest <on|off>", description: "suggest changes" },
2948
+ { flags: "--change <on|off>", description: "make changes when asked" },
2949
+ { flags: "--approve <on|off>", description: "approve when it finds nothing" },
2950
+ { flags: "--merge <on|off>", description: "merge what it approved (needs --approve on)" },
2951
+ { flags: "--project <name>", description: "a project other than this folder's" },
2952
+ ],
2953
+ examples: [
2954
+ "cbx assistant",
2955
+ "cbx assistant automated --review on --describe on",
2956
+ "cbx assistant --approve on --merge on",
2957
+ "cbx assistant manual",
2958
+ ],
2959
+ run: settings_commands_js_1.commandAssistant,
2960
+ },
2961
+ {
2962
+ /*
2963
+ Not `transfer`, which already brings a project in from GitHub, GitLab
2964
+ or Codeberg. This hands one of yours to somebody else.
2965
+ */
2966
+ name: "hand-over",
2967
+ group: "Project settings",
2968
+ summary: "offer a project to another owner, or answer an offer",
2969
+ usage: "hand-over <username|email> [project] [--drop-access] [--yes] | hand-over offers | hand-over accept|decline|cancel <project>",
2970
+ brief: "hand-over <user> [project]",
2971
+ detail: "Offers the project to another account, as the website's Settings →\n" +
2972
+ "Danger zone does. Nothing moves until they accept, and the offer lapses\n" +
2973
+ "after fourteen days. Once accepted it is theirs, and only they can give\n" +
2974
+ "it back, so this asks for TRANSFER to be typed unless --yes is given.\n" +
2975
+ "Only the owner can offer a project.\n\n" +
2976
+ "You keep admin access afterwards unless --drop-access says otherwise.\n" +
2977
+ "`hand-over offers` lists offers to you and by you; accept or decline one\n" +
2978
+ "made to you, or cancel one you made.",
2979
+ options: [
2980
+ { flags: "--drop-access", description: "give up your access when they accept" },
2981
+ { flags: "-y, --yes", description: "offer it without asking, for scripts" },
2982
+ { flags: "--project <name>", description: "a project other than this folder's" },
2983
+ ],
2984
+ examples: [
2985
+ "cbx hand-over sam my-project",
2986
+ "cbx hand-over sam@example.com --drop-access",
2987
+ "cbx hand-over offers",
2988
+ "cbx hand-over accept night-owl-diner",
2989
+ ],
2990
+ run: settings_commands_js_1.commandHandOver,
2991
+ },
2845
2992
  {
2846
2993
  name: "pages",
2847
- group: "Your projects",
2994
+ group: "Project settings",
2848
2995
  summary: "serve a public project as a website",
2849
2996
  usage: "pages [auto|on|off] [project]",
2850
2997
  detail: "With no word, says whether the project's site is on, its address, which\n" +
@@ -2877,9 +3024,10 @@ const SPECS = [
2877
3024
  },
2878
3025
  {
2879
3026
  name: "private",
2880
- group: "Your projects",
3027
+ group: "Project settings",
2881
3028
  summary: "files and folders only the project's own people may see",
2882
3029
  usage: "private [list|add|remove|set] [pattern…] [--project <project>]",
3030
+ brief: "private [list|add|remove|set]",
2883
3031
  detail: "Keeps chosen files out of sight in a public project: visitors, the\n" +
2884
3032
  "public API, git clone, zips, Pages and search leave them out, while\n" +
2885
3033
  "members see everything. Patterns work like a .gitignore:\n\n" +
@@ -2902,9 +3050,10 @@ const SPECS = [
2902
3050
  },
2903
3051
  {
2904
3052
  name: "mods",
2905
- group: "Your projects",
3053
+ group: "Mods and bundles",
2906
3054
  summary: "mod repositories for games: set one up, publish to one",
2907
3055
  usage: "mods <create|repos|info|settings|builds|list|publish|remove|block|reports|delete> …",
3056
+ brief: "mods <action> …",
2908
3057
  detail: "A mod repository is where a game's players get mods from. Its owner\n" +
2909
3058
  "sets the rules — which file types a mod may hold, archives opened and\n" +
2910
3059
  "checked too, the manifest each upload carries, size limits, and whether\n" +
@@ -2968,7 +3117,7 @@ const SPECS = [
2968
3117
  },
2969
3118
  {
2970
3119
  name: "issues",
2971
- group: "Your projects",
3120
+ group: "Issues",
2972
3121
  summary: "issues on a project, or open one",
2973
3122
  usage: "issues [project]",
2974
3123
  detail: "Labels are given when the issue is opened rather than added\n" +
@@ -2990,20 +3139,39 @@ const SPECS = [
2990
3139
  },
2991
3140
  {
2992
3141
  name: "issue",
2993
- group: "Your projects",
2994
- summary: "read, answer, close, label or assign one issue",
2995
- usage: "issue view|comment|close|reopen|label|assign <number> … | issue labels | issue rules",
3142
+ group: "Issues",
3143
+ summary: "read, answer, close, label or assign one issue; labels and rules",
3144
+ usage: "issue view|comment|close|reopen|label|assign <number> … | issue labels [add|change|remove <name>] | issue rules [add <kind> | on|off|change|remove <n>]",
3145
+ brief: "issue <action> [number]",
2996
3146
  detail: "Closing says why: completed (the default), --reason not-planned, or\n" +
2997
3147
  "--duplicate-of <n>. Labels and assignment need write access; replying\n" +
2998
3148
  "needs only read access, as on the website.\n\n" +
3149
+ "The project's labels and issue rules are the website's Settings → Issues.\n" +
3150
+ "`issue labels` lists the labels; add, change and remove manage them.\n" +
3151
+ "`issue rules` lists the rules, numbered; a rule is changed by its number.\n" +
3152
+ "The kinds and what each takes:\n\n" +
3153
+ " auto-label --words <a,b> --label <name> [--in title|body|both]\n" +
3154
+ " auto-assign --assignees <a,b> [--label <name>]\n" +
3155
+ " welcome -m <message>\n" +
3156
+ " stale [--days <n>] [--close-after <n>] [--label] [-m] [--exempt <a,b>]\n\n" +
2999
3157
  "Inside a run, CODEROOK_TOKEN and CODEROOK_PROJECT are set, so a workflow\n" +
3000
3158
  "can comment on or label the issue that started it with no setup.",
3001
3159
  options: [
3002
- { flags: "-m, --message <text>", description: "what to say (comment, or a note when closing)" },
3160
+ { flags: "-m, --message <text>", description: "what to say (comment, a note when closing, a rule's message)" },
3003
3161
  { flags: "--reason <completed|not-planned>", description: "why it is closed" },
3004
3162
  { flags: "--duplicate-of <n>", description: "close as a duplicate of another issue" },
3005
3163
  { flags: "--remove", description: "take the labels off instead" },
3006
3164
  { flags: "--starter", description: "with labels: add the usual set" },
3165
+ { flags: "--colour <hex>", description: "labels add/change: its colour, like d73a4a" },
3166
+ { flags: "--description <text>", description: "labels add/change: what it is for" },
3167
+ { flags: "--name <text>", description: "labels change: rename it" },
3168
+ { flags: "--words <a,b>", description: "rules: words that earn the label (auto-label)" },
3169
+ { flags: "--label <name>", description: "rules: the label to add, or to act on" },
3170
+ { flags: "--in <where>", description: "rules: title, body or both (auto-label)" },
3171
+ { flags: "--assignees <a,b>", description: "rules: who to assign (auto-assign)" },
3172
+ { flags: "--days <n>", description: "rules: quiet days before an issue is stale" },
3173
+ { flags: "--close-after <n>", description: "rules: days after that before it is closed" },
3174
+ { flags: "--exempt <a,b>", description: "rules: labels that keep an issue from going stale" },
3007
3175
  { flags: "--project <name>", description: "which project" },
3008
3176
  ],
3009
3177
  examples: [
@@ -3013,13 +3181,18 @@ const SPECS = [
3013
3181
  "cbx issue label 12 bug,ui",
3014
3182
  "cbx issue assign 12 sam",
3015
3183
  "cbx issue labels --starter",
3184
+ 'cbx issue labels add crash --colour d73a4a --description "It falls over"',
3185
+ "cbx issue labels remove wontfix",
3186
+ "cbx issue rules add auto-label --words crash,freeze --label crash",
3187
+ 'cbx issue rules add welcome -m "Thanks — we read every report."',
3188
+ "cbx issue rules off 2",
3016
3189
  ],
3017
3190
  run: issue_command_js_1.commandIssue,
3018
3191
  },
3019
3192
  {
3020
3193
  name: "releases",
3021
3194
  aliases: ["tags"],
3022
- group: "Your projects",
3195
+ group: "Versions and releases",
3023
3196
  summary: "what has been released, and its files",
3024
3197
  usage: "releases [project]",
3025
3198
  detail: "Each release with its files and who can take them: public (source and\n" +
@@ -3037,7 +3210,7 @@ const SPECS = [
3037
3210
  */
3038
3211
  name: "hooks",
3039
3212
  aliases: ["webhooks"],
3040
- group: "Your projects",
3213
+ group: "Project settings",
3041
3214
  summary: "where this project tells something else what happened",
3042
3215
  usage: "hooks [project]",
3043
3216
  detail: "A signed POST to an address of yours when something happens here.\n" +
@@ -3047,17 +3220,31 @@ const SPECS = [
3047
3220
  "check.reported, change_request.opened, change_request.reviewed,\n" +
3048
3221
  "issue.opened, issue.closed, issue.reopened, issue.commented,\n" +
3049
3222
  "issue.labeled, run.finished, run.failed, release.published.\n" +
3050
- "Naming none of them sends all of them.",
3223
+ "Naming none of them sends all of them.\n\n" +
3224
+ "A hook is named by its id or its address. With only one hook on the\n" +
3225
+ "project, --test, --deliveries, --redeliver and --on need no name.\n" +
3226
+ "Twenty failures in a row switch a hook off; --on switches it back on\n" +
3227
+ "with a clean count.",
3051
3228
  options: [
3052
3229
  { flags: "--add <url>", description: "notify this address; https only" },
3053
- { flags: "--events <a,b>", description: "only these, comma separated" },
3230
+ { flags: "--events <a,b>", description: "only these, comma separated (with --hook: change them; all for every one)" },
3054
3231
  { flags: "--remove <id>", description: "stop notifying it" },
3232
+ { flags: "--hook <id>", description: "which hook --events or --redeliver is about" },
3233
+ { flags: "--test [id]", description: "send a signed ping now and say how it was answered" },
3234
+ { flags: "--deliveries [id]", description: "the most recent deliveries and how each went" },
3235
+ { flags: "--redeliver <delivery>", description: "send a delivery again (the start of its id is enough)" },
3236
+ { flags: "--on [id]", description: "switch a hook that was switched off back on" },
3055
3237
  { flags: "--project <name>", description: "which project" },
3056
3238
  ],
3057
3239
  examples: [
3058
3240
  "cbx hooks",
3059
3241
  "cbx hooks --add https://example.com/coderook",
3060
3242
  "cbx hooks --add https://example.com/builds --events version.published",
3243
+ "cbx hooks --test",
3244
+ "cbx hooks --deliveries 3f2a9c10-…",
3245
+ "cbx hooks --redeliver 7b1e04aa --hook 3f2a9c10-…",
3246
+ "cbx hooks --hook 3f2a9c10-… --events release.published,run.failed",
3247
+ "cbx hooks --on 3f2a9c10-…",
3061
3248
  ],
3062
3249
  run: service_commands_js_1.commandHooks,
3063
3250
  },
@@ -3070,7 +3257,7 @@ const SPECS = [
3070
3257
  This moves the project.
3071
3258
  */
3072
3259
  name: "undo",
3073
- group: "Your projects",
3260
+ group: "Versions and releases",
3074
3261
  summary: "put the project back on an earlier save",
3075
3262
  usage: "undo [n] [project]",
3076
3263
  detail: "Goes back one save unless you name another to go back to.\n\n" +
@@ -3089,7 +3276,7 @@ const SPECS = [
3089
3276
  actually offers.
3090
3277
  */
3091
3278
  name: "promote",
3092
- group: "Your projects",
3279
+ group: "Versions and releases",
3093
3280
  summary: "turn a commit into a version people can fetch",
3094
3281
  usage: "promote [n] [project]",
3095
3282
  detail: "Shows the last ten commits and asks which one. Give a number to skip\n" +
@@ -3125,7 +3312,7 @@ const SPECS = [
3125
3312
  hides it, labels it — which is what it does anyway.
3126
3313
  */
3127
3314
  name: "attach",
3128
- group: "Your projects",
3315
+ group: "Versions and releases",
3129
3316
  summary: "put a file people can download on a version",
3130
3317
  usage: "attach <file> [n] [project]",
3131
3318
  detail: "A version can carry downloads — an installer, a build, a changelog —\n" +
@@ -3150,7 +3337,7 @@ const SPECS = [
3150
3337
  {
3151
3338
  name: "notes",
3152
3339
  aliases: ["release-notes"],
3153
- group: "Your projects",
3340
+ group: "Versions and releases",
3154
3341
  summary: "read or write what a version says about itself",
3155
3342
  usage: "notes [n] [project]",
3156
3343
  detail: "The release info the website shows on a version, and the same field\n" +
@@ -3178,7 +3365,7 @@ const SPECS = [
3178
3365
  {
3179
3366
  name: "mark",
3180
3367
  aliases: ["set"],
3181
- group: "Your projects",
3368
+ group: "Versions and releases",
3182
3369
  summary: "name, hide, pin or label one save",
3183
3370
  usage: "mark [n] [project]",
3184
3371
  detail: "Changes the newest version unless you name another.\n" +
@@ -3210,9 +3397,10 @@ const SPECS = [
3210
3397
  },
3211
3398
  {
3212
3399
  name: "labels",
3213
- group: "Your projects",
3400
+ group: "Versions and releases",
3214
3401
  summary: "the labels this project puts on versions",
3215
3402
  usage: "labels [list|add|remove] [name] [colour]",
3403
+ brief: "labels [list|add|remove]",
3216
3404
  detail: "A label is a name and a colour. Put as many on a version as you like —\n" +
3217
3405
  "how you group and colour your own history is yours to decide.",
3218
3406
  examples: [
@@ -3226,7 +3414,7 @@ const SPECS = [
3226
3414
  {
3227
3415
  name: "held",
3228
3416
  aliases: ["waiting"],
3229
- group: "Your projects",
3417
+ group: "Versions and releases",
3230
3418
  summary: "versions waiting for somebody to approve them",
3231
3419
  usage: "held [project]",
3232
3420
  detail: "A project can be set to hold pushes from anyone below admin until an\n" +
@@ -3236,9 +3424,10 @@ const SPECS = [
3236
3424
  },
3237
3425
  {
3238
3426
  name: "review",
3239
- group: "Your projects",
3427
+ group: "Versions and releases",
3240
3428
  summary: "accept a held version, or turn it down",
3241
3429
  usage: "review <n> --approve | --decline",
3430
+ brief: "review <n> --approve|--decline",
3242
3431
  options: [
3243
3432
  {
3244
3433
  flags: "--approve",
@@ -3260,7 +3449,7 @@ const SPECS = [
3260
3449
  saying what was removed and by whom.
3261
3450
  */
3262
3451
  name: "take-down",
3263
- group: "Your projects",
3452
+ group: "Versions and releases",
3264
3453
  summary: "remove a version's files, for something published by mistake",
3265
3454
  usage: "take-down <n> --yes",
3266
3455
  detail: "The files go and do not come back. The version stays in the history as\n" +
@@ -3280,7 +3469,7 @@ const SPECS = [
3280
3469
  */
3281
3470
  name: "release",
3282
3471
  aliases: ["tag"],
3283
- group: "Your projects",
3472
+ group: "Versions and releases",
3284
3473
  summary: "give a version a name, so people know which one to fetch",
3285
3474
  usage: "release <name> [project]",
3286
3475
  detail: "Names the newest version unless you name another with --version.\n" +
@@ -3315,9 +3504,10 @@ const SPECS = [
3315
3504
  },
3316
3505
  {
3317
3506
  name: "fork",
3318
- group: "Your projects",
3507
+ group: "Project settings",
3319
3508
  summary: "your own copy of somebody's project, and offering work back",
3320
3509
  usage: "fork <owner/project> [--name <slug>] | fork offer [line] --title <text> | fork sync",
3510
+ brief: "fork <owner/project>",
3321
3511
  detail: "A fork is a private project under your account with the original's latest\n" +
3322
3512
  "public version (its private files left out). Nothing is uploaded again.\n\n" +
3323
3513
  "Inside a fork, `cbx fork offer <line>` offers that line to the original as\n" +
@@ -3336,32 +3526,44 @@ const SPECS = [
3336
3526
  },
3337
3527
  {
3338
3528
  name: "security",
3339
- group: "Your projects",
3340
- summary: "report a vulnerability privately, or handle reports",
3341
- usage: "security report <owner/project> --title <text> | security list | view|reply|mark S-<n>",
3529
+ group: "Project settings",
3530
+ summary: "report a vulnerability privately, handle reports, set the policy",
3531
+ usage: "security report <owner/project> --title <text> | security list | view|reply|mark S-<n> | security policy [--on|--off] [--text <file>]",
3532
+ brief: "security <action> [S-n]",
3342
3533
  detail: "A report is seen only by the project's owner and admins, and by whoever\n" +
3343
3534
  "sent it. Please use this rather than a public issue for anything that\n" +
3344
- "could hurt people using the project.",
3535
+ "could hurt people using the project.\n\n" +
3536
+ "`security policy` shows whether the project takes private reports and\n" +
3537
+ "what it tells people about sending one (the website's Settings →\n" +
3538
+ "Security). --text reads a file when one by that name exists, and uses\n" +
3539
+ "the words themselves otherwise. Owners and admins change it.",
3345
3540
  options: [
3346
3541
  { flags: "--title <text>", description: "report: what is wrong" },
3347
3542
  { flags: "--body <text>", description: "report: details and how to reproduce it" },
3348
3543
  { flags: "--severity <level>", description: "report: low, medium, high or critical" },
3349
3544
  { flags: "-m, --message <text>", description: "reply: what to say" },
3350
- { flags: "--project <name>", description: "list/view/reply/mark: which project" },
3545
+ { flags: "--on", description: "policy: take private reports" },
3546
+ { flags: "--off", description: "policy: stop taking them" },
3547
+ { flags: "--text <file or text>", description: "policy: the reporting policy" },
3548
+ { flags: "--clear", description: "policy: remove the written policy" },
3549
+ { flags: "--project <name>", description: "list/view/reply/mark/policy: which project" },
3351
3550
  ],
3352
3551
  examples: [
3353
3552
  'cbx security report sam/editor --title "Path traversal in export" --severity high',
3354
3553
  "cbx security list",
3355
3554
  'cbx security reply S-3 -m "Confirmed; fix in 2.0.1"',
3356
3555
  "cbx security mark S-3 fixed",
3556
+ "cbx security policy",
3557
+ "cbx security policy --on --text SECURITY.md",
3357
3558
  ],
3358
3559
  run: community_command_js_1.commandSecurity,
3359
3560
  },
3360
3561
  {
3361
3562
  name: "verify",
3362
- group: "Your projects",
3563
+ group: "Versions and releases",
3363
3564
  summary: "check a download against its release's signed manifest",
3364
3565
  usage: "verify <owner/project> <release> <file…>",
3566
+ brief: "verify <owner/project> …",
3365
3567
  detail: "Every public release has a manifest listing each file with its size and\n" +
3366
3568
  "SHA-256, signed with CodeRook's release key. This checks the signature,\n" +
3367
3569
  "then the files you downloaded. A mismatch means do not run it.",
@@ -3371,7 +3573,7 @@ const SPECS = [
3371
3573
  },
3372
3574
  {
3373
3575
  name: "deps",
3374
- group: "Your projects",
3576
+ group: "Versions and releases",
3375
3577
  summary: "known vulnerabilities in a save's dependencies",
3376
3578
  usage: "deps [version]",
3377
3579
  detail: "Reads the lockfiles in the save (package-lock.json, yarn.lock,\n" +
@@ -3389,7 +3591,7 @@ const SPECS = [
3389
3591
  {
3390
3592
  name: "actions",
3391
3593
  aliases: ["workflows"],
3392
- group: "Your projects",
3594
+ group: "Actions and builds",
3393
3595
  summary: "the automations a project has",
3394
3596
  usage: "actions [project]",
3395
3597
  detail: "Shows what each action runs, what it runs on, and how many of its\n" +
@@ -3429,9 +3631,10 @@ const SPECS = [
3429
3631
  },
3430
3632
  {
3431
3633
  name: "pr",
3432
- group: "Working with a folder",
3634
+ group: "Lines, merges and pull requests",
3433
3635
  summary: "pull requests: list, read, review, comment, merge",
3434
3636
  usage: "pr <list|view|files|comment|approve|request-changes|ask|label|title|ready|draft|retarget|close|reopen|merge> [M-3] …",
3637
+ brief: "pr <action> [M-3]",
3435
3638
  detail: "A pull request is a line offered to another line (cbx propose opens one).\n" +
3436
3639
  "This is the Pull requests tab of the website, from here:\n\n" +
3437
3640
  " list [--all|--state merged] [--mine] [--label bug] the project's pull requests\n" +
@@ -3474,7 +3677,7 @@ const SPECS = [
3474
3677
  },
3475
3678
  {
3476
3679
  name: "cancel",
3477
- group: "Actions",
3680
+ group: "Actions and builds",
3478
3681
  summary: "stop a run that is waiting or working",
3479
3682
  usage: "cancel <number> [project]",
3480
3683
  detail: "Marks the run cancelled at once. A runner working on it is told at its next\n" +
@@ -3484,7 +3687,7 @@ const SPECS = [
3484
3687
  },
3485
3688
  {
3486
3689
  name: "rerun",
3487
- group: "Actions",
3690
+ group: "Actions and builds",
3488
3691
  summary: "run a finished run again",
3489
3692
  usage: "rerun <number> [project]",
3490
3693
  detail: "Queues the same action against the same save. When the run was checking a\n" +
@@ -3494,7 +3697,7 @@ const SPECS = [
3494
3697
  },
3495
3698
  {
3496
3699
  name: "approve",
3497
- group: "Actions",
3700
+ group: "Actions and builds",
3498
3701
  summary: "let a run that waits for approval start",
3499
3702
  usage: "approve <number> [project]",
3500
3703
  detail: "An action marked as needing approval (often one that publishes) waits\n" +
@@ -3505,9 +3708,10 @@ const SPECS = [
3505
3708
  {
3506
3709
  name: "secret",
3507
3710
  aliases: ["secrets"],
3508
- group: "Actions",
3711
+ group: "Project settings",
3509
3712
  summary: "values runs need that must not be in the files",
3510
3713
  usage: "secret list | set <NAME> | remove <NAME>",
3714
+ brief: "secret list|set|remove [NAME]",
3511
3715
  detail: "A secret is handed to each run as an environment variable of the same\n" +
3512
3716
  "name, but only to runs started by people who can change the project.\n" +
3513
3717
  "Run logs show *** in its place. Its value is never shown again.\n\n" +
@@ -3528,7 +3732,7 @@ const SPECS = [
3528
3732
  },
3529
3733
  {
3530
3734
  name: "runs",
3531
- group: "Actions",
3735
+ group: "Actions and builds",
3532
3736
  summary: "what has run, and how it went",
3533
3737
  usage: "runs [project]",
3534
3738
  detail: "Newest first, with the machine that took each one. A run that is still\n" +
@@ -3545,7 +3749,7 @@ const SPECS = [
3545
3749
  },
3546
3750
  {
3547
3751
  name: "logs",
3548
- group: "Actions",
3752
+ group: "Actions and builds",
3549
3753
  summary: "what one run printed",
3550
3754
  usage: "logs <number> [project]",
3551
3755
  detail: "The output the runner sent up, in order. Anything the command wrote to\n" +
@@ -3557,7 +3761,7 @@ const SPECS = [
3557
3761
  },
3558
3762
  {
3559
3763
  name: "delete",
3560
- group: "Your projects",
3764
+ group: "Project settings",
3561
3765
  summary: "delete a project",
3562
3766
  usage: "delete [project]",
3563
3767
  detail: "Asks for the project name to be typed before it does anything. The\n" +
@@ -3569,25 +3773,34 @@ const SPECS = [
3569
3773
  {
3570
3774
  name: "people",
3571
3775
  aliases: ["collaborators"],
3572
- group: "People",
3573
- summary: "who can reach a project, and invite somebody",
3776
+ group: "Project settings",
3777
+ summary: "who can reach a project: invite, change a role, remove",
3574
3778
  usage: "people [project]",
3779
+ detail: "Lists the project's people and the invites waiting on a reply. Somebody\n" +
3780
+ "is named by their email address or display name, as the list shows them.\n" +
3781
+ "Only the project's owner and admins can see the list or change it.",
3575
3782
  options: [
3576
3783
  { flags: "--invite <email>", description: "ask somebody to join" },
3577
- { flags: "--role <role>", description: "write, read or admin (default write)" },
3784
+ { flags: "--role <role>", description: "write, read or admin (default write when inviting)" },
3785
+ { flags: "--change <who>", description: "give one of the project's people the --role named" },
3786
+ { flags: "--remove <who>", description: "take somebody off the project" },
3787
+ { flags: "--cancel-invite <email>", description: "withdraw an invite nobody has accepted" },
3578
3788
  { flags: "--accept <link>", description: "join a project you were invited to" },
3579
3789
  ],
3580
3790
  examples: [
3581
3791
  "cbx people my-project --invite sam@example.com",
3792
+ "cbx people --change sam@example.com --role admin",
3793
+ "cbx people --remove sam@example.com",
3582
3794
  "cbx people --accept https://coderook.com/?invite=…",
3583
3795
  ],
3584
3796
  run: service_commands_js_1.commandCollaborators,
3585
3797
  },
3586
3798
  {
3587
3799
  name: "watch",
3588
- group: "People",
3800
+ group: "Project settings",
3589
3801
  summary: "what reaches you about a project",
3590
3802
  usage: "watch [project] [--level versions]",
3803
+ brief: "watch [project]",
3591
3804
  options: [
3592
3805
  {
3593
3806
  flags: "--level <level>",
@@ -3599,7 +3812,7 @@ const SPECS = [
3599
3812
  },
3600
3813
  {
3601
3814
  name: "tokens",
3602
- group: "Other",
3815
+ group: "For assistants",
3603
3816
  summary: "the tokens that can act as your account",
3604
3817
  usage: "tokens",
3605
3818
  detail: "Lists personal access tokens with when each was last used, which is\n" +
@@ -3610,9 +3823,10 @@ const SPECS = [
3610
3823
  },
3611
3824
  {
3612
3825
  name: "propose",
3613
- group: "Working with a folder",
3826
+ group: "Lines, merges and pull requests",
3614
3827
  summary: "offer this folder's line to main",
3615
3828
  usage: 'propose -m "title" [--into main] [--body text] [folder]',
3829
+ brief: "propose -m \"title\" [folder]",
3616
3830
  options: [
3617
3831
  { flags: "-m, --message <text>", description: "the proposal's title" },
3618
3832
  { flags: "--into <line>", description: "the line to propose into (default main)" },
@@ -3627,7 +3841,7 @@ const SPECS = [
3627
3841
  },
3628
3842
  {
3629
3843
  name: "proposals",
3630
- group: "Working with a folder",
3844
+ group: "Lines, merges and pull requests",
3631
3845
  summary: "open proposals on this project",
3632
3846
  usage: "proposals [--all] [folder]",
3633
3847
  options: [{ flags: "--all", description: "include merged and cancelled ones" }],
@@ -3635,7 +3849,7 @@ const SPECS = [
3635
3849
  },
3636
3850
  {
3637
3851
  name: "merges",
3638
- group: "When somebody saved first",
3852
+ group: "Lines, merges and pull requests",
3639
3853
  summary: "this folder's uploads waiting on a decision",
3640
3854
  usage: "merges [folder]",
3641
3855
  detail: "Both merge commands read the project this folder is linked to, so run\n" +
@@ -3644,7 +3858,7 @@ const SPECS = [
3644
3858
  },
3645
3859
  {
3646
3860
  name: "merge",
3647
- group: "When somebody saved first",
3861
+ group: "Lines, merges and pull requests",
3648
3862
  summary: "merge a line here, or decide one waiting on CodeRook",
3649
3863
  usage: "merge <line | ref>",
3650
3864
  detail: "In a folder with a history of its own, merges a line or a save into\n" +
@@ -3668,21 +3882,21 @@ const SPECS = [
3668
3882
  },
3669
3883
  {
3670
3884
  name: "bundle",
3671
- group: "Bundles",
3885
+ group: "Mods and bundles",
3672
3886
  summary: "pack the project as a .cbx",
3673
3887
  usage: "bundle [folder] [out]",
3674
3888
  run: commandBundle,
3675
3889
  },
3676
3890
  {
3677
3891
  name: "unbundle",
3678
- group: "Bundles",
3892
+ group: "Mods and bundles",
3679
3893
  summary: "extract a .cbx",
3680
3894
  usage: "unbundle <file> [dir]",
3681
3895
  run: commandUnbundle,
3682
3896
  },
3683
3897
  {
3684
3898
  name: "inspect",
3685
- group: "Bundles",
3899
+ group: "Mods and bundles",
3686
3900
  summary: "what a .cbx contains",
3687
3901
  usage: "inspect <file>",
3688
3902
  options: [{ flags: "--files", description: "list every file inside" }],
@@ -3690,7 +3904,7 @@ const SPECS = [
3690
3904
  },
3691
3905
  {
3692
3906
  name: "runner",
3693
- group: "Actions",
3907
+ group: "Actions and builds",
3694
3908
  summary: "take this project's runs and do them here",
3695
3909
  usage: "runner <project>",
3696
3910
  detail: "Claims queued runs for a project and executes them on this machine.\n" +
@@ -3712,7 +3926,7 @@ const SPECS = [
3712
3926
  is a file in a folder, and this already knows where the folder is.
3713
3927
  */
3714
3928
  name: "skill",
3715
- group: "Other",
3929
+ group: "For assistants",
3716
3930
  summary: "teach Claude Code about CodeRook",
3717
3931
  usage: "skill [--project]",
3718
3932
  detail: "Writes a short guide into Claude Code's skills folder, so it knows what\n" +
@@ -3744,7 +3958,7 @@ const SPECS = [
3744
3958
  stdin and stdout, and exits with them.
3745
3959
  */
3746
3960
  name: "mcp",
3747
- group: "Other",
3961
+ group: "For assistants",
3748
3962
  summary: "serve CodeRook to Claude Code, Codex and other assistants",
3749
3963
  usage: "mcp [--workspaces]",
3750
3964
  options: [{ flags: "--workspaces", description: "opt into the remote connector's write/run/deploy tools and workspace permissions" }],
@@ -3772,7 +3986,7 @@ const SPECS = [
3772
3986
  },
3773
3987
  {
3774
3988
  name: "doctor",
3775
- group: "Other",
3989
+ group: "Getting started",
3776
3990
  summary: "check the service, config and sign-in",
3777
3991
  usage: "doctor",
3778
3992
  run: () => commandDoctor(),
@@ -3797,9 +4011,10 @@ function localTwin(name, original, local, row, extra) {
3797
4011
  }
3798
4012
  SPECS.push({
3799
4013
  name: "build",
3800
- group: "Actions",
4014
+ group: "Actions and builds",
3801
4015
  summary: "build executables for Windows, Linux and macOS on this machine",
3802
4016
  usage: "build [folder] [--target win,linux,mac]",
4017
+ brief: "build [folder] [--target …]",
3803
4018
  detail: "Builds the project in this folder for each target, using whatever this\n" +
3804
4019
  "machine has: Go, Bun, Deno and .NET build every platform from any one;\n" +
3805
4020
  "Rust does with cargo-zigbuild; Electron builds Linux from Windows with\n" +
@@ -3848,7 +4063,8 @@ SPECS.push(localTwin("push", "submit", local_commands_js_1.localPush, {
3848
4063
  "Anywhere else, this is `cbx get`.",
3849
4064
  examples: ["cbx pull", "cbx pull my-project"],
3850
4065
  }, [{ flags: "-f, --force", description: "discard unsaved changes that are in the way" }]));
3851
- const REGISTRY = (0, registry_js_1.buildRegistry)(SPECS);
4066
+ /* Exported for the help test (test/help_listing.test.ts); nothing else imports this file. */
4067
+ exports.REGISTRY = (0, registry_js_1.buildRegistry)(SPECS);
3852
4068
  async function main(argv) {
3853
4069
  const old = (0, node_check_js_1.nodeTooOld)();
3854
4070
  if (old) {
@@ -3857,7 +4073,7 @@ async function main(argv) {
3857
4073
  }
3858
4074
  const [name, ...rest] = argv;
3859
4075
  if (!name || name === "--help" || name === "-h") {
3860
- console.log((0, help_js_1.renderHelp)(REGISTRY, version_js_1.VERSION));
4076
+ console.log((0, help_js_1.renderHelp)(exports.REGISTRY, version_js_1.VERSION));
3861
4077
  return 0;
3862
4078
  }
3863
4079
  if (name === "--version" || name === "-v" || name === "version") {
@@ -3872,20 +4088,20 @@ async function main(argv) {
3872
4088
  if (name === "help") {
3873
4089
  const wanted = rest[0];
3874
4090
  if (!wanted) {
3875
- console.log((0, help_js_1.renderHelp)(REGISTRY, version_js_1.VERSION));
4091
+ console.log((0, help_js_1.renderHelp)(exports.REGISTRY, version_js_1.VERSION));
3876
4092
  return 0;
3877
4093
  }
3878
- const spec = REGISTRY.lookup.get(wanted);
4094
+ const spec = exports.REGISTRY.lookup.get(wanted);
3879
4095
  if (!spec) {
3880
- console.error((0, help_js_1.renderUnknown)(wanted, (0, registry_js_1.nearestCommand)(REGISTRY, wanted)));
4096
+ console.error((0, help_js_1.renderUnknown)(wanted, (0, registry_js_1.nearestCommand)(exports.REGISTRY, wanted)));
3881
4097
  return 1;
3882
4098
  }
3883
4099
  console.log((0, help_js_1.renderCommandHelp)(spec));
3884
4100
  return 0;
3885
4101
  }
3886
- const spec = REGISTRY.lookup.get(name);
4102
+ const spec = exports.REGISTRY.lookup.get(name);
3887
4103
  if (!spec) {
3888
- console.error((0, help_js_1.renderUnknown)(name, (0, registry_js_1.nearestCommand)(REGISTRY, name)));
4104
+ console.error((0, help_js_1.renderUnknown)(name, (0, registry_js_1.nearestCommand)(exports.REGISTRY, name)));
3889
4105
  return 1;
3890
4106
  }
3891
4107
  if (rest.includes("--help") || rest.includes("-h")) {
@@ -3908,10 +4124,17 @@ async function main(argv) {
3908
4124
  function leave(code) {
3909
4125
  node_process_1.default.exitCode = code;
3910
4126
  }
3911
- (0, network_js_1.tuneNetwork)();
3912
- main(node_process_1.default.argv.slice(2))
3913
- .then(leave)
3914
- .catch((error) => {
3915
- console.error(red((0, network_js_1.describeError)(error)));
3916
- leave(1);
3917
- });
4127
+ /*
4128
+ Run only when started as the program. A test loads this file to read the
4129
+ command table — that every command is listed once, and fits — and must not
4130
+ find itself running a command with the test runner's own arguments.
4131
+ */
4132
+ if (require.main === module) {
4133
+ (0, network_js_1.tuneNetwork)();
4134
+ main(node_process_1.default.argv.slice(2))
4135
+ .then(leave)
4136
+ .catch((error) => {
4137
+ console.error(red((0, network_js_1.describeError)(error)));
4138
+ leave(1);
4139
+ });
4140
+ }