@rebasepro/cli 0.12.1-canary.gdd7172e → 0.12.1-canary.ge1bb178

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.es.js CHANGED
@@ -1009,6 +1009,22 @@ function ensureProjectId(projectRoot) {
1009
1009
  }
1010
1010
  return projectId;
1011
1011
  }
1012
+ //#endregion
1013
+ //#region src/telemetry/project.ts
1014
+ function readProjectPolicy(startDir = process.cwd()) {
1015
+ try {
1016
+ const root = findProjectRoot(startDir);
1017
+ if (!root) return "unset";
1018
+ const file = path.join(root, MANIFEST_FILENAME);
1019
+ if (!fs.existsSync(file)) return "unset";
1020
+ const raw = fs.readFileSync(file, "utf-8");
1021
+ const match = /"telemetry"\s*:\s*(true|false)/.exec(raw);
1022
+ if (!match) return "unset";
1023
+ return match[1] === "false" ? "opt_out" : "ignored_opt_in";
1024
+ } catch {
1025
+ return "unset";
1026
+ }
1027
+ }
1012
1028
  function endpoint() {
1013
1029
  return process.env.REBASE_TELEMETRY_ENDPOINT?.trim() || "https://app.rebase.pro/api/functions/telemetry";
1014
1030
  }
@@ -1026,18 +1042,23 @@ function endpoint() {
1026
1042
  * `CI` is refused for a different reason: a build runner is not a person, and
1027
1043
  * counting one is both useless and misleading. A single pipeline re-running on
1028
1044
  * every push would otherwise outweigh every real developer in the data.
1045
+ *
1046
+ * A project's own `"telemetry": false` is checked *before* the machine setting,
1047
+ * because it has to beat an individual opt-in to be worth anything — see
1048
+ * project.ts on why the reverse is refused.
1029
1049
  */
1030
- function suppressionReason(env = process.env) {
1050
+ function suppressionReason(env = process.env, cwd = process.cwd()) {
1031
1051
  if (env.DO_NOT_TRACK && env.DO_NOT_TRACK !== "0") return "do_not_track";
1032
1052
  if (env.REBASE_TELEMETRY_DISABLED && env.REBASE_TELEMETRY_DISABLED !== "0") return "rebase_telemetry_disabled";
1033
1053
  if (env.CI && env.CI !== "false") return "ci";
1054
+ if (readProjectPolicy(cwd) === "opt_out") return "project_opt_out";
1034
1055
  const config = readConfig();
1035
1056
  if (config.enabled === void 0) return "not_asked";
1036
1057
  if (!config.enabled) return "declined";
1037
1058
  return null;
1038
1059
  }
1039
- function isEnabled(env = process.env) {
1040
- return suppressionReason(env) === null;
1060
+ function isEnabled(env = process.env, cwd = process.cwd()) {
1061
+ return suppressionReason(env, cwd) === null;
1041
1062
  }
1042
1063
  /** Record the user's answer. `false` is final — nothing prompts again. */
1043
1064
  function setConsent(enabled) {
@@ -1081,7 +1102,7 @@ function previewEvent(event, properties = {}, projectRoot) {
1081
1102
  */
1082
1103
  async function recordEvent(event, properties = {}, options = {}) {
1083
1104
  try {
1084
- if (!isEnabled()) return;
1105
+ if (!isEnabled(process.env, options.projectRoot ?? process.cwd())) return;
1085
1106
  const payload = buildEvent(event, properties, {
1086
1107
  machineId: ensureMachineId(),
1087
1108
  projectId: options.projectRoot ? ensureProjectId(options.projectRoot) : void 0
@@ -1185,6 +1206,7 @@ function describeState(env = process.env) {
1185
1206
  case "do_not_track": return `${chalk.gray("disabled")} — the ${chalk.cyan("DO_NOT_TRACK")} environment variable is set`;
1186
1207
  case "rebase_telemetry_disabled": return `${chalk.gray("disabled")} — the ${chalk.cyan("REBASE_TELEMETRY_DISABLED")} environment variable is set`;
1187
1208
  case "ci": return `${chalk.gray("disabled")} — this looks like CI (${chalk.cyan("CI")} is set), which is never counted`;
1209
+ case "project_opt_out": return `${chalk.gray("disabled")} — this project's ${chalk.cyan("rebase.json")} sets ${chalk.cyan("\"telemetry\": false")}`;
1188
1210
  }
1189
1211
  }
1190
1212
  //#endregion
@@ -5992,6 +6014,12 @@ async function telemetryCommand(rawArgs) {
5992
6014
  function printStatus() {
5993
6015
  console.log("");
5994
6016
  console.log(` Status: ${describeState()}`);
6017
+ if (readProjectPolicy() === "ignored_opt_in") {
6018
+ console.log("");
6019
+ console.log(chalk.yellow(" Note: this project's rebase.json sets \"telemetry\": true, which is ignored."));
6020
+ console.log(chalk.gray(" A committed file cannot consent on behalf of everyone who clones it."));
6021
+ console.log(chalk.gray(` Only "telemetry": false is honoured there. Use ${chalk.cyan("rebase telemetry enable")}.`));
6022
+ }
5995
6023
  console.log(` Endpoint: ${chalk.gray(endpoint())}`);
5996
6024
  console.log(` Config: ${chalk.gray(configPath())}`);
5997
6025
  console.log("");
@@ -6028,6 +6056,11 @@ ${chalk.bold("Commands")}
6028
6056
  ${chalk.blue("enable")} Start sharing
6029
6057
  ${chalk.blue("disable")} Stop sharing, permanently
6030
6058
 
6059
+ ${chalk.bold("Project policy")}
6060
+ ${chalk.blue("\"telemetry\": false")} in ${chalk.blue("rebase.json")} disables sharing for everyone who
6061
+ clones the repository, overriding each developer's own choice.
6062
+ ${chalk.gray("\"telemetry\": true is ignored — a committed file cannot consent for others.")}
6063
+
6031
6064
  ${chalk.bold("Environment")}
6032
6065
  ${chalk.blue("DO_NOT_TRACK")} Set to disable, across every tool that honours it
6033
6066
  ${chalk.blue("REBASE_TELEMETRY_DISABLED")} Set to disable Rebase specifically