@coderook/cli 0.39.0 → 0.41.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,182 @@ 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
+ /* Settings → General → Features: which parts a project has, and who sees each. */
2871
+ name: "features",
2872
+ group: "Project settings",
2873
+ summary: "which parts a project has, and who sees each",
2874
+ usage: "features [project] [--issues <choice>] [--pulls <choice>] [--actions <choice>] [--analytics <choice>] [--collaborators <choice>] [--storage <choice>]",
2875
+ brief: "features [project]",
2876
+ detail: "Shows each part of the project and who sees it, and changes them.\n" +
2877
+ "A choice is off (the tab goes for everybody), members (the project's\n" +
2878
+ "own people) or everyone (visitors to a public project too: they read\n" +
2879
+ "issues, pull requests and runs, and anyone signed in can open issues\n" +
2880
+ "and comment). Storage is never everyone's: it is your account's quota.",
2881
+ options: [
2882
+ { flags: "--issues <choice>", description: "off, members or everyone" },
2883
+ { flags: "--pulls <choice>", description: "pull requests: off, members or everyone" },
2884
+ { flags: "--actions <choice>", description: "runs and their logs: off, members or everyone" },
2885
+ { flags: "--analytics <choice>", description: "off, members or everyone" },
2886
+ { flags: "--collaborators <choice>", description: "who works on it: off, members or everyone" },
2887
+ { flags: "--storage <choice>", description: "off or members" },
2888
+ { flags: "--project <name>", description: "a project other than this folder's" },
2889
+ ],
2890
+ examples: ["cbx features", "cbx features --issues everyone --pulls everyone", "cbx features my-project --analytics off"],
2891
+ run: settings_commands_js_1.commandFeatures,
2892
+ },
2893
+ {
2894
+ /*
2895
+ Beside `cbx tracks` rather than inside it. That lists where somebody can
2896
+ save and is read all day; these are the rules an owner sets once.
2897
+ */
2898
+ name: "line-rules",
2899
+ group: "Lines, merges and pull requests",
2900
+ summary: "protection, approvals and required checks on each line",
2901
+ usage: "line-rules [line] [--protect|--unprotect] [--approvals <n>] [--checks <a,b>] [--code-owners on|off] [--project <p>]",
2902
+ brief: "line-rules [line] [options]",
2903
+ detail: "With no line, lists every line with its rules and the code owners read\n" +
2904
+ "from the default line's CODEOWNERS file. Name a line to change it — the\n" +
2905
+ "website's Settings → Lines & reviews. Only the owner and admins can.\n\n" +
2906
+ "A protected line refuses restores and merges that would overwrite it.\n" +
2907
+ "Approvals is how many people must approve before a merge may land (0 to\n" +
2908
+ "10). Checks are the names that must pass, comma separated; none clears\n" +
2909
+ "them. Code owners on means a code owner of what changed must approve.",
2910
+ options: [
2911
+ { flags: "--protect", description: "protect the line" },
2912
+ { flags: "--unprotect", description: "stop protecting it" },
2913
+ { flags: "--approvals <n>", description: "approvals a merge needs, 0 to 10" },
2914
+ { flags: "--checks <a,b>", description: "checks that must pass; none for no checks" },
2915
+ { flags: "--code-owners <on|off>", description: "whether a code owner must approve" },
2916
+ { flags: "--project <name>", description: "a project other than this folder's" },
2917
+ ],
2918
+ examples: [
2919
+ "cbx line-rules",
2920
+ "cbx line-rules main --protect --approvals 1",
2921
+ "cbx line-rules main --checks build,test --code-owners on",
2922
+ "cbx line-rules release --unprotect --checks none",
2923
+ ],
2924
+ run: settings_commands_js_1.commandLineRules,
2925
+ },
2926
+ {
2927
+ name: "upload-rules",
2928
+ group: "Project settings",
2929
+ summary: "what uploads leave out, and encrypting secret files",
2930
+ usage: "upload-rules [--ignore <file>] [--keep <file>] [--encrypt on|off] [--warn-large <MiB>] [--hold-pushes on|off] [--project <p>]",
2931
+ brief: "upload-rules [options]",
2932
+ detail: "The project's upload rules — the website's Settings → Files & privacy →\n" +
2933
+ "Encrypted uploads. The desktop app and the website's scans read them.\n" +
2934
+ "Ignore rules leave files out; keep rules bring back what an ignore rule\n" +
2935
+ "caught. Both are read from a file of patterns, one per line, in the\n" +
2936
+ "shape of a .gitignore; none clears them. This folder's own ignore file\n" +
2937
+ "is `cbx ignore`.\n\n" +
2938
+ "--encrypt covers files recognised as secrets before they are stored.\n" +
2939
+ "--hold-pushes makes saves from anybody below admin wait for an admin to\n" +
2940
+ "accept them (see `cbx held`). Owners and admins change these.",
2941
+ options: [
2942
+ { flags: "--ignore <file>", description: "replace the ignore rules with this file's" },
2943
+ { flags: "--keep <file>", description: "replace the keep rules with this file's" },
2944
+ { flags: "--encrypt <on|off>", description: "encrypt files recognised as secrets" },
2945
+ { flags: "--warn-large <MiB>", description: "warn about files larger than this" },
2946
+ { flags: "--hold-pushes <on|off>", description: "saves below admin wait to be accepted" },
2947
+ { flags: "--project <name>", description: "a project other than this folder's" },
2948
+ ],
2949
+ examples: [
2950
+ "cbx upload-rules",
2951
+ "cbx upload-rules --ignore .coderookignore --warn-large 512",
2952
+ "cbx upload-rules --encrypt on --keep none",
2953
+ ],
2954
+ run: settings_commands_js_1.commandUploadRules,
2955
+ },
2956
+ {
2957
+ name: "assistant",
2958
+ group: "Project settings",
2959
+ summary: "the pull-request assistant: when it works and what it may do",
2960
+ usage: "assistant [manual|automated] [project] [--review on|off] [--describe on|off] [--suggest on|off] [--change on|off] [--approve on|off] [--merge on|off]",
2961
+ brief: "assistant [manual|automated]",
2962
+ detail: "Manual means it works only when somebody asks on a pull request.\n" +
2963
+ "Automated means it works on its own, doing what is switched on:\n" +
2964
+ "reviewing, describing, suggesting, changing, approving and merging.\n" +
2965
+ "Merging needs approving on too. Automated comes with a subscription on\n" +
2966
+ "the owner's account. Only the project's admins change it — the\n" +
2967
+ "website's Settings → Automation.",
2968
+ options: [
2969
+ { flags: "--review <on|off>", description: "review each pull request" },
2970
+ { flags: "--describe <on|off>", description: "write the description" },
2971
+ { flags: "--suggest <on|off>", description: "suggest changes" },
2972
+ { flags: "--change <on|off>", description: "make changes when asked" },
2973
+ { flags: "--approve <on|off>", description: "approve when it finds nothing" },
2974
+ { flags: "--merge <on|off>", description: "merge what it approved (needs --approve on)" },
2975
+ { flags: "--project <name>", description: "a project other than this folder's" },
2976
+ ],
2977
+ examples: [
2978
+ "cbx assistant",
2979
+ "cbx assistant automated --review on --describe on",
2980
+ "cbx assistant --approve on --merge on",
2981
+ "cbx assistant manual",
2982
+ ],
2983
+ run: settings_commands_js_1.commandAssistant,
2984
+ },
2985
+ {
2986
+ /*
2987
+ Not `transfer`, which already brings a project in from GitHub, GitLab
2988
+ or Codeberg. This hands one of yours to somebody else.
2989
+ */
2990
+ name: "hand-over",
2991
+ group: "Project settings",
2992
+ summary: "offer a project to another owner, or answer an offer",
2993
+ usage: "hand-over <username|email> [project] [--drop-access] [--yes] | hand-over offers | hand-over accept|decline|cancel <project>",
2994
+ brief: "hand-over <user> [project]",
2995
+ detail: "Offers the project to another account, as the website's Settings →\n" +
2996
+ "Danger zone does. Nothing moves until they accept, and the offer lapses\n" +
2997
+ "after fourteen days. Once accepted it is theirs, and only they can give\n" +
2998
+ "it back, so this asks for TRANSFER to be typed unless --yes is given.\n" +
2999
+ "Only the owner can offer a project.\n\n" +
3000
+ "You keep admin access afterwards unless --drop-access says otherwise.\n" +
3001
+ "`hand-over offers` lists offers to you and by you; accept or decline one\n" +
3002
+ "made to you, or cancel one you made.",
3003
+ options: [
3004
+ { flags: "--drop-access", description: "give up your access when they accept" },
3005
+ { flags: "-y, --yes", description: "offer it without asking, for scripts" },
3006
+ { flags: "--project <name>", description: "a project other than this folder's" },
3007
+ ],
3008
+ examples: [
3009
+ "cbx hand-over sam my-project",
3010
+ "cbx hand-over sam@example.com --drop-access",
3011
+ "cbx hand-over offers",
3012
+ "cbx hand-over accept night-owl-diner",
3013
+ ],
3014
+ run: settings_commands_js_1.commandHandOver,
3015
+ },
2845
3016
  {
2846
3017
  name: "pages",
2847
- group: "Your projects",
3018
+ group: "Project settings",
2848
3019
  summary: "serve a public project as a website",
2849
3020
  usage: "pages [auto|on|off] [project]",
2850
3021
  detail: "With no word, says whether the project's site is on, its address, which\n" +
@@ -2877,9 +3048,10 @@ const SPECS = [
2877
3048
  },
2878
3049
  {
2879
3050
  name: "private",
2880
- group: "Your projects",
3051
+ group: "Project settings",
2881
3052
  summary: "files and folders only the project's own people may see",
2882
3053
  usage: "private [list|add|remove|set] [pattern…] [--project <project>]",
3054
+ brief: "private [list|add|remove|set]",
2883
3055
  detail: "Keeps chosen files out of sight in a public project: visitors, the\n" +
2884
3056
  "public API, git clone, zips, Pages and search leave them out, while\n" +
2885
3057
  "members see everything. Patterns work like a .gitignore:\n\n" +
@@ -2902,9 +3074,10 @@ const SPECS = [
2902
3074
  },
2903
3075
  {
2904
3076
  name: "mods",
2905
- group: "Your projects",
3077
+ group: "Mods and bundles",
2906
3078
  summary: "mod repositories for games: set one up, publish to one",
2907
3079
  usage: "mods <create|repos|info|settings|builds|list|publish|remove|block|reports|delete> …",
3080
+ brief: "mods <action> …",
2908
3081
  detail: "A mod repository is where a game's players get mods from. Its owner\n" +
2909
3082
  "sets the rules — which file types a mod may hold, archives opened and\n" +
2910
3083
  "checked too, the manifest each upload carries, size limits, and whether\n" +
@@ -2968,7 +3141,7 @@ const SPECS = [
2968
3141
  },
2969
3142
  {
2970
3143
  name: "issues",
2971
- group: "Your projects",
3144
+ group: "Issues",
2972
3145
  summary: "issues on a project, or open one",
2973
3146
  usage: "issues [project]",
2974
3147
  detail: "Labels are given when the issue is opened rather than added\n" +
@@ -2990,20 +3163,39 @@ const SPECS = [
2990
3163
  },
2991
3164
  {
2992
3165
  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",
3166
+ group: "Issues",
3167
+ summary: "read, answer, close, label or assign one issue; labels and rules",
3168
+ usage: "issue view|comment|close|reopen|label|assign <number> … | issue labels [add|change|remove <name>] | issue rules [add <kind> | on|off|change|remove <n>]",
3169
+ brief: "issue <action> [number]",
2996
3170
  detail: "Closing says why: completed (the default), --reason not-planned, or\n" +
2997
3171
  "--duplicate-of <n>. Labels and assignment need write access; replying\n" +
2998
3172
  "needs only read access, as on the website.\n\n" +
3173
+ "The project's labels and issue rules are the website's Settings → Issues.\n" +
3174
+ "`issue labels` lists the labels; add, change and remove manage them.\n" +
3175
+ "`issue rules` lists the rules, numbered; a rule is changed by its number.\n" +
3176
+ "The kinds and what each takes:\n\n" +
3177
+ " auto-label --words <a,b> --label <name> [--in title|body|both]\n" +
3178
+ " auto-assign --assignees <a,b> [--label <name>]\n" +
3179
+ " welcome -m <message>\n" +
3180
+ " stale [--days <n>] [--close-after <n>] [--label] [-m] [--exempt <a,b>]\n\n" +
2999
3181
  "Inside a run, CODEROOK_TOKEN and CODEROOK_PROJECT are set, so a workflow\n" +
3000
3182
  "can comment on or label the issue that started it with no setup.",
3001
3183
  options: [
3002
- { flags: "-m, --message <text>", description: "what to say (comment, or a note when closing)" },
3184
+ { flags: "-m, --message <text>", description: "what to say (comment, a note when closing, a rule's message)" },
3003
3185
  { flags: "--reason <completed|not-planned>", description: "why it is closed" },
3004
3186
  { flags: "--duplicate-of <n>", description: "close as a duplicate of another issue" },
3005
3187
  { flags: "--remove", description: "take the labels off instead" },
3006
3188
  { flags: "--starter", description: "with labels: add the usual set" },
3189
+ { flags: "--colour <hex>", description: "labels add/change: its colour, like d73a4a" },
3190
+ { flags: "--description <text>", description: "labels add/change: what it is for" },
3191
+ { flags: "--name <text>", description: "labels change: rename it" },
3192
+ { flags: "--words <a,b>", description: "rules: words that earn the label (auto-label)" },
3193
+ { flags: "--label <name>", description: "rules: the label to add, or to act on" },
3194
+ { flags: "--in <where>", description: "rules: title, body or both (auto-label)" },
3195
+ { flags: "--assignees <a,b>", description: "rules: who to assign (auto-assign)" },
3196
+ { flags: "--days <n>", description: "rules: quiet days before an issue is stale" },
3197
+ { flags: "--close-after <n>", description: "rules: days after that before it is closed" },
3198
+ { flags: "--exempt <a,b>", description: "rules: labels that keep an issue from going stale" },
3007
3199
  { flags: "--project <name>", description: "which project" },
3008
3200
  ],
3009
3201
  examples: [
@@ -3013,13 +3205,18 @@ const SPECS = [
3013
3205
  "cbx issue label 12 bug,ui",
3014
3206
  "cbx issue assign 12 sam",
3015
3207
  "cbx issue labels --starter",
3208
+ 'cbx issue labels add crash --colour d73a4a --description "It falls over"',
3209
+ "cbx issue labels remove wontfix",
3210
+ "cbx issue rules add auto-label --words crash,freeze --label crash",
3211
+ 'cbx issue rules add welcome -m "Thanks — we read every report."',
3212
+ "cbx issue rules off 2",
3016
3213
  ],
3017
3214
  run: issue_command_js_1.commandIssue,
3018
3215
  },
3019
3216
  {
3020
3217
  name: "releases",
3021
3218
  aliases: ["tags"],
3022
- group: "Your projects",
3219
+ group: "Versions and releases",
3023
3220
  summary: "what has been released, and its files",
3024
3221
  usage: "releases [project]",
3025
3222
  detail: "Each release with its files and who can take them: public (source and\n" +
@@ -3037,7 +3234,7 @@ const SPECS = [
3037
3234
  */
3038
3235
  name: "hooks",
3039
3236
  aliases: ["webhooks"],
3040
- group: "Your projects",
3237
+ group: "Project settings",
3041
3238
  summary: "where this project tells something else what happened",
3042
3239
  usage: "hooks [project]",
3043
3240
  detail: "A signed POST to an address of yours when something happens here.\n" +
@@ -3047,17 +3244,31 @@ const SPECS = [
3047
3244
  "check.reported, change_request.opened, change_request.reviewed,\n" +
3048
3245
  "issue.opened, issue.closed, issue.reopened, issue.commented,\n" +
3049
3246
  "issue.labeled, run.finished, run.failed, release.published.\n" +
3050
- "Naming none of them sends all of them.",
3247
+ "Naming none of them sends all of them.\n\n" +
3248
+ "A hook is named by its id or its address. With only one hook on the\n" +
3249
+ "project, --test, --deliveries, --redeliver and --on need no name.\n" +
3250
+ "Twenty failures in a row switch a hook off; --on switches it back on\n" +
3251
+ "with a clean count.",
3051
3252
  options: [
3052
3253
  { flags: "--add <url>", description: "notify this address; https only" },
3053
- { flags: "--events <a,b>", description: "only these, comma separated" },
3254
+ { flags: "--events <a,b>", description: "only these, comma separated (with --hook: change them; all for every one)" },
3054
3255
  { flags: "--remove <id>", description: "stop notifying it" },
3256
+ { flags: "--hook <id>", description: "which hook --events or --redeliver is about" },
3257
+ { flags: "--test [id]", description: "send a signed ping now and say how it was answered" },
3258
+ { flags: "--deliveries [id]", description: "the most recent deliveries and how each went" },
3259
+ { flags: "--redeliver <delivery>", description: "send a delivery again (the start of its id is enough)" },
3260
+ { flags: "--on [id]", description: "switch a hook that was switched off back on" },
3055
3261
  { flags: "--project <name>", description: "which project" },
3056
3262
  ],
3057
3263
  examples: [
3058
3264
  "cbx hooks",
3059
3265
  "cbx hooks --add https://example.com/coderook",
3060
3266
  "cbx hooks --add https://example.com/builds --events version.published",
3267
+ "cbx hooks --test",
3268
+ "cbx hooks --deliveries 3f2a9c10-…",
3269
+ "cbx hooks --redeliver 7b1e04aa --hook 3f2a9c10-…",
3270
+ "cbx hooks --hook 3f2a9c10-… --events release.published,run.failed",
3271
+ "cbx hooks --on 3f2a9c10-…",
3061
3272
  ],
3062
3273
  run: service_commands_js_1.commandHooks,
3063
3274
  },
@@ -3070,7 +3281,7 @@ const SPECS = [
3070
3281
  This moves the project.
3071
3282
  */
3072
3283
  name: "undo",
3073
- group: "Your projects",
3284
+ group: "Versions and releases",
3074
3285
  summary: "put the project back on an earlier save",
3075
3286
  usage: "undo [n] [project]",
3076
3287
  detail: "Goes back one save unless you name another to go back to.\n\n" +
@@ -3089,7 +3300,7 @@ const SPECS = [
3089
3300
  actually offers.
3090
3301
  */
3091
3302
  name: "promote",
3092
- group: "Your projects",
3303
+ group: "Versions and releases",
3093
3304
  summary: "turn a commit into a version people can fetch",
3094
3305
  usage: "promote [n] [project]",
3095
3306
  detail: "Shows the last ten commits and asks which one. Give a number to skip\n" +
@@ -3125,7 +3336,7 @@ const SPECS = [
3125
3336
  hides it, labels it — which is what it does anyway.
3126
3337
  */
3127
3338
  name: "attach",
3128
- group: "Your projects",
3339
+ group: "Versions and releases",
3129
3340
  summary: "put a file people can download on a version",
3130
3341
  usage: "attach <file> [n] [project]",
3131
3342
  detail: "A version can carry downloads — an installer, a build, a changelog —\n" +
@@ -3150,7 +3361,7 @@ const SPECS = [
3150
3361
  {
3151
3362
  name: "notes",
3152
3363
  aliases: ["release-notes"],
3153
- group: "Your projects",
3364
+ group: "Versions and releases",
3154
3365
  summary: "read or write what a version says about itself",
3155
3366
  usage: "notes [n] [project]",
3156
3367
  detail: "The release info the website shows on a version, and the same field\n" +
@@ -3178,7 +3389,7 @@ const SPECS = [
3178
3389
  {
3179
3390
  name: "mark",
3180
3391
  aliases: ["set"],
3181
- group: "Your projects",
3392
+ group: "Versions and releases",
3182
3393
  summary: "name, hide, pin or label one save",
3183
3394
  usage: "mark [n] [project]",
3184
3395
  detail: "Changes the newest version unless you name another.\n" +
@@ -3210,9 +3421,10 @@ const SPECS = [
3210
3421
  },
3211
3422
  {
3212
3423
  name: "labels",
3213
- group: "Your projects",
3424
+ group: "Versions and releases",
3214
3425
  summary: "the labels this project puts on versions",
3215
3426
  usage: "labels [list|add|remove] [name] [colour]",
3427
+ brief: "labels [list|add|remove]",
3216
3428
  detail: "A label is a name and a colour. Put as many on a version as you like —\n" +
3217
3429
  "how you group and colour your own history is yours to decide.",
3218
3430
  examples: [
@@ -3226,7 +3438,7 @@ const SPECS = [
3226
3438
  {
3227
3439
  name: "held",
3228
3440
  aliases: ["waiting"],
3229
- group: "Your projects",
3441
+ group: "Versions and releases",
3230
3442
  summary: "versions waiting for somebody to approve them",
3231
3443
  usage: "held [project]",
3232
3444
  detail: "A project can be set to hold pushes from anyone below admin until an\n" +
@@ -3236,9 +3448,10 @@ const SPECS = [
3236
3448
  },
3237
3449
  {
3238
3450
  name: "review",
3239
- group: "Your projects",
3451
+ group: "Versions and releases",
3240
3452
  summary: "accept a held version, or turn it down",
3241
3453
  usage: "review <n> --approve | --decline",
3454
+ brief: "review <n> --approve|--decline",
3242
3455
  options: [
3243
3456
  {
3244
3457
  flags: "--approve",
@@ -3260,7 +3473,7 @@ const SPECS = [
3260
3473
  saying what was removed and by whom.
3261
3474
  */
3262
3475
  name: "take-down",
3263
- group: "Your projects",
3476
+ group: "Versions and releases",
3264
3477
  summary: "remove a version's files, for something published by mistake",
3265
3478
  usage: "take-down <n> --yes",
3266
3479
  detail: "The files go and do not come back. The version stays in the history as\n" +
@@ -3280,7 +3493,7 @@ const SPECS = [
3280
3493
  */
3281
3494
  name: "release",
3282
3495
  aliases: ["tag"],
3283
- group: "Your projects",
3496
+ group: "Versions and releases",
3284
3497
  summary: "give a version a name, so people know which one to fetch",
3285
3498
  usage: "release <name> [project]",
3286
3499
  detail: "Names the newest version unless you name another with --version.\n" +
@@ -3315,9 +3528,10 @@ const SPECS = [
3315
3528
  },
3316
3529
  {
3317
3530
  name: "fork",
3318
- group: "Your projects",
3531
+ group: "Project settings",
3319
3532
  summary: "your own copy of somebody's project, and offering work back",
3320
3533
  usage: "fork <owner/project> [--name <slug>] | fork offer [line] --title <text> | fork sync",
3534
+ brief: "fork <owner/project>",
3321
3535
  detail: "A fork is a private project under your account with the original's latest\n" +
3322
3536
  "public version (its private files left out). Nothing is uploaded again.\n\n" +
3323
3537
  "Inside a fork, `cbx fork offer <line>` offers that line to the original as\n" +
@@ -3336,32 +3550,44 @@ const SPECS = [
3336
3550
  },
3337
3551
  {
3338
3552
  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>",
3553
+ group: "Project settings",
3554
+ summary: "report a vulnerability privately, handle reports, set the policy",
3555
+ usage: "security report <owner/project> --title <text> | security list | view|reply|mark S-<n> | security policy [--on|--off] [--text <file>]",
3556
+ brief: "security <action> [S-n]",
3342
3557
  detail: "A report is seen only by the project's owner and admins, and by whoever\n" +
3343
3558
  "sent it. Please use this rather than a public issue for anything that\n" +
3344
- "could hurt people using the project.",
3559
+ "could hurt people using the project.\n\n" +
3560
+ "`security policy` shows whether the project takes private reports and\n" +
3561
+ "what it tells people about sending one (the website's Settings →\n" +
3562
+ "Security). --text reads a file when one by that name exists, and uses\n" +
3563
+ "the words themselves otherwise. Owners and admins change it.",
3345
3564
  options: [
3346
3565
  { flags: "--title <text>", description: "report: what is wrong" },
3347
3566
  { flags: "--body <text>", description: "report: details and how to reproduce it" },
3348
3567
  { flags: "--severity <level>", description: "report: low, medium, high or critical" },
3349
3568
  { flags: "-m, --message <text>", description: "reply: what to say" },
3350
- { flags: "--project <name>", description: "list/view/reply/mark: which project" },
3569
+ { flags: "--on", description: "policy: take private reports" },
3570
+ { flags: "--off", description: "policy: stop taking them" },
3571
+ { flags: "--text <file or text>", description: "policy: the reporting policy" },
3572
+ { flags: "--clear", description: "policy: remove the written policy" },
3573
+ { flags: "--project <name>", description: "list/view/reply/mark/policy: which project" },
3351
3574
  ],
3352
3575
  examples: [
3353
3576
  'cbx security report sam/editor --title "Path traversal in export" --severity high',
3354
3577
  "cbx security list",
3355
3578
  'cbx security reply S-3 -m "Confirmed; fix in 2.0.1"',
3356
3579
  "cbx security mark S-3 fixed",
3580
+ "cbx security policy",
3581
+ "cbx security policy --on --text SECURITY.md",
3357
3582
  ],
3358
3583
  run: community_command_js_1.commandSecurity,
3359
3584
  },
3360
3585
  {
3361
3586
  name: "verify",
3362
- group: "Your projects",
3587
+ group: "Versions and releases",
3363
3588
  summary: "check a download against its release's signed manifest",
3364
3589
  usage: "verify <owner/project> <release> <file…>",
3590
+ brief: "verify <owner/project> …",
3365
3591
  detail: "Every public release has a manifest listing each file with its size and\n" +
3366
3592
  "SHA-256, signed with CodeRook's release key. This checks the signature,\n" +
3367
3593
  "then the files you downloaded. A mismatch means do not run it.",
@@ -3371,7 +3597,7 @@ const SPECS = [
3371
3597
  },
3372
3598
  {
3373
3599
  name: "deps",
3374
- group: "Your projects",
3600
+ group: "Versions and releases",
3375
3601
  summary: "known vulnerabilities in a save's dependencies",
3376
3602
  usage: "deps [version]",
3377
3603
  detail: "Reads the lockfiles in the save (package-lock.json, yarn.lock,\n" +
@@ -3389,7 +3615,7 @@ const SPECS = [
3389
3615
  {
3390
3616
  name: "actions",
3391
3617
  aliases: ["workflows"],
3392
- group: "Your projects",
3618
+ group: "Actions and builds",
3393
3619
  summary: "the automations a project has",
3394
3620
  usage: "actions [project]",
3395
3621
  detail: "Shows what each action runs, what it runs on, and how many of its\n" +
@@ -3429,9 +3655,10 @@ const SPECS = [
3429
3655
  },
3430
3656
  {
3431
3657
  name: "pr",
3432
- group: "Working with a folder",
3658
+ group: "Lines, merges and pull requests",
3433
3659
  summary: "pull requests: list, read, review, comment, merge",
3434
3660
  usage: "pr <list|view|files|comment|approve|request-changes|ask|label|title|ready|draft|retarget|close|reopen|merge> [M-3] …",
3661
+ brief: "pr <action> [M-3]",
3435
3662
  detail: "A pull request is a line offered to another line (cbx propose opens one).\n" +
3436
3663
  "This is the Pull requests tab of the website, from here:\n\n" +
3437
3664
  " list [--all|--state merged] [--mine] [--label bug] the project's pull requests\n" +
@@ -3474,7 +3701,7 @@ const SPECS = [
3474
3701
  },
3475
3702
  {
3476
3703
  name: "cancel",
3477
- group: "Actions",
3704
+ group: "Actions and builds",
3478
3705
  summary: "stop a run that is waiting or working",
3479
3706
  usage: "cancel <number> [project]",
3480
3707
  detail: "Marks the run cancelled at once. A runner working on it is told at its next\n" +
@@ -3484,7 +3711,7 @@ const SPECS = [
3484
3711
  },
3485
3712
  {
3486
3713
  name: "rerun",
3487
- group: "Actions",
3714
+ group: "Actions and builds",
3488
3715
  summary: "run a finished run again",
3489
3716
  usage: "rerun <number> [project]",
3490
3717
  detail: "Queues the same action against the same save. When the run was checking a\n" +
@@ -3494,7 +3721,7 @@ const SPECS = [
3494
3721
  },
3495
3722
  {
3496
3723
  name: "approve",
3497
- group: "Actions",
3724
+ group: "Actions and builds",
3498
3725
  summary: "let a run that waits for approval start",
3499
3726
  usage: "approve <number> [project]",
3500
3727
  detail: "An action marked as needing approval (often one that publishes) waits\n" +
@@ -3505,9 +3732,10 @@ const SPECS = [
3505
3732
  {
3506
3733
  name: "secret",
3507
3734
  aliases: ["secrets"],
3508
- group: "Actions",
3735
+ group: "Project settings",
3509
3736
  summary: "values runs need that must not be in the files",
3510
3737
  usage: "secret list | set <NAME> | remove <NAME>",
3738
+ brief: "secret list|set|remove [NAME]",
3511
3739
  detail: "A secret is handed to each run as an environment variable of the same\n" +
3512
3740
  "name, but only to runs started by people who can change the project.\n" +
3513
3741
  "Run logs show *** in its place. Its value is never shown again.\n\n" +
@@ -3528,7 +3756,7 @@ const SPECS = [
3528
3756
  },
3529
3757
  {
3530
3758
  name: "runs",
3531
- group: "Actions",
3759
+ group: "Actions and builds",
3532
3760
  summary: "what has run, and how it went",
3533
3761
  usage: "runs [project]",
3534
3762
  detail: "Newest first, with the machine that took each one. A run that is still\n" +
@@ -3545,7 +3773,7 @@ const SPECS = [
3545
3773
  },
3546
3774
  {
3547
3775
  name: "logs",
3548
- group: "Actions",
3776
+ group: "Actions and builds",
3549
3777
  summary: "what one run printed",
3550
3778
  usage: "logs <number> [project]",
3551
3779
  detail: "The output the runner sent up, in order. Anything the command wrote to\n" +
@@ -3557,7 +3785,7 @@ const SPECS = [
3557
3785
  },
3558
3786
  {
3559
3787
  name: "delete",
3560
- group: "Your projects",
3788
+ group: "Project settings",
3561
3789
  summary: "delete a project",
3562
3790
  usage: "delete [project]",
3563
3791
  detail: "Asks for the project name to be typed before it does anything. The\n" +
@@ -3569,25 +3797,34 @@ const SPECS = [
3569
3797
  {
3570
3798
  name: "people",
3571
3799
  aliases: ["collaborators"],
3572
- group: "People",
3573
- summary: "who can reach a project, and invite somebody",
3800
+ group: "Project settings",
3801
+ summary: "who can reach a project: invite, change a role, remove",
3574
3802
  usage: "people [project]",
3803
+ detail: "Lists the project's people and the invites waiting on a reply. Somebody\n" +
3804
+ "is named by their email address or display name, as the list shows them.\n" +
3805
+ "Only the project's owner and admins can see the list or change it.",
3575
3806
  options: [
3576
3807
  { flags: "--invite <email>", description: "ask somebody to join" },
3577
- { flags: "--role <role>", description: "write, read or admin (default write)" },
3808
+ { flags: "--role <role>", description: "write, read or admin (default write when inviting)" },
3809
+ { flags: "--change <who>", description: "give one of the project's people the --role named" },
3810
+ { flags: "--remove <who>", description: "take somebody off the project" },
3811
+ { flags: "--cancel-invite <email>", description: "withdraw an invite nobody has accepted" },
3578
3812
  { flags: "--accept <link>", description: "join a project you were invited to" },
3579
3813
  ],
3580
3814
  examples: [
3581
3815
  "cbx people my-project --invite sam@example.com",
3816
+ "cbx people --change sam@example.com --role admin",
3817
+ "cbx people --remove sam@example.com",
3582
3818
  "cbx people --accept https://coderook.com/?invite=…",
3583
3819
  ],
3584
3820
  run: service_commands_js_1.commandCollaborators,
3585
3821
  },
3586
3822
  {
3587
3823
  name: "watch",
3588
- group: "People",
3824
+ group: "Project settings",
3589
3825
  summary: "what reaches you about a project",
3590
3826
  usage: "watch [project] [--level versions]",
3827
+ brief: "watch [project]",
3591
3828
  options: [
3592
3829
  {
3593
3830
  flags: "--level <level>",
@@ -3599,7 +3836,7 @@ const SPECS = [
3599
3836
  },
3600
3837
  {
3601
3838
  name: "tokens",
3602
- group: "Other",
3839
+ group: "For assistants",
3603
3840
  summary: "the tokens that can act as your account",
3604
3841
  usage: "tokens",
3605
3842
  detail: "Lists personal access tokens with when each was last used, which is\n" +
@@ -3610,9 +3847,10 @@ const SPECS = [
3610
3847
  },
3611
3848
  {
3612
3849
  name: "propose",
3613
- group: "Working with a folder",
3850
+ group: "Lines, merges and pull requests",
3614
3851
  summary: "offer this folder's line to main",
3615
3852
  usage: 'propose -m "title" [--into main] [--body text] [folder]',
3853
+ brief: "propose -m \"title\" [folder]",
3616
3854
  options: [
3617
3855
  { flags: "-m, --message <text>", description: "the proposal's title" },
3618
3856
  { flags: "--into <line>", description: "the line to propose into (default main)" },
@@ -3627,7 +3865,7 @@ const SPECS = [
3627
3865
  },
3628
3866
  {
3629
3867
  name: "proposals",
3630
- group: "Working with a folder",
3868
+ group: "Lines, merges and pull requests",
3631
3869
  summary: "open proposals on this project",
3632
3870
  usage: "proposals [--all] [folder]",
3633
3871
  options: [{ flags: "--all", description: "include merged and cancelled ones" }],
@@ -3635,7 +3873,7 @@ const SPECS = [
3635
3873
  },
3636
3874
  {
3637
3875
  name: "merges",
3638
- group: "When somebody saved first",
3876
+ group: "Lines, merges and pull requests",
3639
3877
  summary: "this folder's uploads waiting on a decision",
3640
3878
  usage: "merges [folder]",
3641
3879
  detail: "Both merge commands read the project this folder is linked to, so run\n" +
@@ -3644,7 +3882,7 @@ const SPECS = [
3644
3882
  },
3645
3883
  {
3646
3884
  name: "merge",
3647
- group: "When somebody saved first",
3885
+ group: "Lines, merges and pull requests",
3648
3886
  summary: "merge a line here, or decide one waiting on CodeRook",
3649
3887
  usage: "merge <line | ref>",
3650
3888
  detail: "In a folder with a history of its own, merges a line or a save into\n" +
@@ -3668,21 +3906,21 @@ const SPECS = [
3668
3906
  },
3669
3907
  {
3670
3908
  name: "bundle",
3671
- group: "Bundles",
3909
+ group: "Mods and bundles",
3672
3910
  summary: "pack the project as a .cbx",
3673
3911
  usage: "bundle [folder] [out]",
3674
3912
  run: commandBundle,
3675
3913
  },
3676
3914
  {
3677
3915
  name: "unbundle",
3678
- group: "Bundles",
3916
+ group: "Mods and bundles",
3679
3917
  summary: "extract a .cbx",
3680
3918
  usage: "unbundle <file> [dir]",
3681
3919
  run: commandUnbundle,
3682
3920
  },
3683
3921
  {
3684
3922
  name: "inspect",
3685
- group: "Bundles",
3923
+ group: "Mods and bundles",
3686
3924
  summary: "what a .cbx contains",
3687
3925
  usage: "inspect <file>",
3688
3926
  options: [{ flags: "--files", description: "list every file inside" }],
@@ -3690,7 +3928,7 @@ const SPECS = [
3690
3928
  },
3691
3929
  {
3692
3930
  name: "runner",
3693
- group: "Actions",
3931
+ group: "Actions and builds",
3694
3932
  summary: "take this project's runs and do them here",
3695
3933
  usage: "runner <project>",
3696
3934
  detail: "Claims queued runs for a project and executes them on this machine.\n" +
@@ -3712,7 +3950,7 @@ const SPECS = [
3712
3950
  is a file in a folder, and this already knows where the folder is.
3713
3951
  */
3714
3952
  name: "skill",
3715
- group: "Other",
3953
+ group: "For assistants",
3716
3954
  summary: "teach Claude Code about CodeRook",
3717
3955
  usage: "skill [--project]",
3718
3956
  detail: "Writes a short guide into Claude Code's skills folder, so it knows what\n" +
@@ -3744,7 +3982,7 @@ const SPECS = [
3744
3982
  stdin and stdout, and exits with them.
3745
3983
  */
3746
3984
  name: "mcp",
3747
- group: "Other",
3985
+ group: "For assistants",
3748
3986
  summary: "serve CodeRook to Claude Code, Codex and other assistants",
3749
3987
  usage: "mcp [--workspaces]",
3750
3988
  options: [{ flags: "--workspaces", description: "opt into the remote connector's write/run/deploy tools and workspace permissions" }],
@@ -3772,7 +4010,7 @@ const SPECS = [
3772
4010
  },
3773
4011
  {
3774
4012
  name: "doctor",
3775
- group: "Other",
4013
+ group: "Getting started",
3776
4014
  summary: "check the service, config and sign-in",
3777
4015
  usage: "doctor",
3778
4016
  run: () => commandDoctor(),
@@ -3797,9 +4035,10 @@ function localTwin(name, original, local, row, extra) {
3797
4035
  }
3798
4036
  SPECS.push({
3799
4037
  name: "build",
3800
- group: "Actions",
4038
+ group: "Actions and builds",
3801
4039
  summary: "build executables for Windows, Linux and macOS on this machine",
3802
4040
  usage: "build [folder] [--target win,linux,mac]",
4041
+ brief: "build [folder] [--target …]",
3803
4042
  detail: "Builds the project in this folder for each target, using whatever this\n" +
3804
4043
  "machine has: Go, Bun, Deno and .NET build every platform from any one;\n" +
3805
4044
  "Rust does with cargo-zigbuild; Electron builds Linux from Windows with\n" +
@@ -3848,7 +4087,8 @@ SPECS.push(localTwin("push", "submit", local_commands_js_1.localPush, {
3848
4087
  "Anywhere else, this is `cbx get`.",
3849
4088
  examples: ["cbx pull", "cbx pull my-project"],
3850
4089
  }, [{ flags: "-f, --force", description: "discard unsaved changes that are in the way" }]));
3851
- const REGISTRY = (0, registry_js_1.buildRegistry)(SPECS);
4090
+ /* Exported for the help test (test/help_listing.test.ts); nothing else imports this file. */
4091
+ exports.REGISTRY = (0, registry_js_1.buildRegistry)(SPECS);
3852
4092
  async function main(argv) {
3853
4093
  const old = (0, node_check_js_1.nodeTooOld)();
3854
4094
  if (old) {
@@ -3857,7 +4097,7 @@ async function main(argv) {
3857
4097
  }
3858
4098
  const [name, ...rest] = argv;
3859
4099
  if (!name || name === "--help" || name === "-h") {
3860
- console.log((0, help_js_1.renderHelp)(REGISTRY, version_js_1.VERSION));
4100
+ console.log((0, help_js_1.renderHelp)(exports.REGISTRY, version_js_1.VERSION));
3861
4101
  return 0;
3862
4102
  }
3863
4103
  if (name === "--version" || name === "-v" || name === "version") {
@@ -3872,20 +4112,20 @@ async function main(argv) {
3872
4112
  if (name === "help") {
3873
4113
  const wanted = rest[0];
3874
4114
  if (!wanted) {
3875
- console.log((0, help_js_1.renderHelp)(REGISTRY, version_js_1.VERSION));
4115
+ console.log((0, help_js_1.renderHelp)(exports.REGISTRY, version_js_1.VERSION));
3876
4116
  return 0;
3877
4117
  }
3878
- const spec = REGISTRY.lookup.get(wanted);
4118
+ const spec = exports.REGISTRY.lookup.get(wanted);
3879
4119
  if (!spec) {
3880
- console.error((0, help_js_1.renderUnknown)(wanted, (0, registry_js_1.nearestCommand)(REGISTRY, wanted)));
4120
+ console.error((0, help_js_1.renderUnknown)(wanted, (0, registry_js_1.nearestCommand)(exports.REGISTRY, wanted)));
3881
4121
  return 1;
3882
4122
  }
3883
4123
  console.log((0, help_js_1.renderCommandHelp)(spec));
3884
4124
  return 0;
3885
4125
  }
3886
- const spec = REGISTRY.lookup.get(name);
4126
+ const spec = exports.REGISTRY.lookup.get(name);
3887
4127
  if (!spec) {
3888
- console.error((0, help_js_1.renderUnknown)(name, (0, registry_js_1.nearestCommand)(REGISTRY, name)));
4128
+ console.error((0, help_js_1.renderUnknown)(name, (0, registry_js_1.nearestCommand)(exports.REGISTRY, name)));
3889
4129
  return 1;
3890
4130
  }
3891
4131
  if (rest.includes("--help") || rest.includes("-h")) {
@@ -3908,10 +4148,17 @@ async function main(argv) {
3908
4148
  function leave(code) {
3909
4149
  node_process_1.default.exitCode = code;
3910
4150
  }
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
- });
4151
+ /*
4152
+ Run only when started as the program. A test loads this file to read the
4153
+ command table — that every command is listed once, and fits — and must not
4154
+ find itself running a command with the test runner's own arguments.
4155
+ */
4156
+ if (require.main === module) {
4157
+ (0, network_js_1.tuneNetwork)();
4158
+ main(node_process_1.default.argv.slice(2))
4159
+ .then(leave)
4160
+ .catch((error) => {
4161
+ console.error(red((0, network_js_1.describeError)(error)));
4162
+ leave(1);
4163
+ });
4164
+ }