@swmansion/argent 0.22.1-next.6 → 0.22.1-next.7

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/cli-cmds.mjs CHANGED
@@ -3274,8 +3274,8 @@ function describeExpectedValue(def) {
3274
3274
  var CONFIG_SCHEMA = [
3275
3275
  {
3276
3276
  key: "telemetry.enabled",
3277
- description: "Whether anonymous opt-out telemetry is enabled (on by default; environment opt-outs like DO_NOT_TRACK are not reflected here \u2014 `argent telemetry status` shows effective consent).",
3278
- scopes: ["global"],
3277
+ description: "Whether anonymous opt-out telemetry is enabled (on by default; environment opt-outs like DO_NOT_TRACK are not reflected here \u2014 `argent telemetry status` shows effective consent). `false` in either scope wins, so a committed project opt-out holds for every teammate.",
3278
+ scopes: ["project", "global"],
3279
3279
  parse: asBoolean,
3280
3280
  merge: "prioritize-restrictive",
3281
3281
  // Opt-out: consent.ts reads an unstored value as enabled, so the config
@@ -7210,7 +7210,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
7210
7210
  var SESSION_ID2 = randomUUID5();
7211
7211
  function readCliVersion() {
7212
7212
  if (true) {
7213
- return "0.22.1-next.6";
7213
+ return "0.22.1-next.7";
7214
7214
  }
7215
7215
  return "0.0.0";
7216
7216
  }
@@ -7572,32 +7572,30 @@ function resolveHostFingerprintAsync() {
7572
7572
 
7573
7573
  // ../telemetry/src/consent.ts
7574
7574
  import * as fs9 from "node:fs";
7575
- var cache = { current: null };
7575
+ var cache = /* @__PURE__ */ new Map();
7576
7576
  var sessionOverride = null;
7577
- function readConfigOverride() {
7577
+ function readConfigOverrideAt(filePath) {
7578
+ const miss = { mtimeMs: null, fingerprint: null, enabledOverride: null };
7578
7579
  let stats;
7579
7580
  try {
7580
- stats = fs9.lstatSync(configFilePath());
7581
- } catch (err) {
7582
- if (err.code === "ENOENT") {
7583
- cache.current = { mtimeMs: null, fingerprint: null, enabledOverride: null };
7584
- return null;
7585
- }
7586
- cache.current = { mtimeMs: null, fingerprint: null, enabledOverride: null };
7581
+ stats = fs9.lstatSync(filePath);
7582
+ } catch {
7583
+ cache.set(filePath, miss);
7587
7584
  return null;
7588
7585
  }
7589
7586
  if (!stats.isFile()) {
7590
- cache.current = { mtimeMs: null, fingerprint: null, enabledOverride: null };
7587
+ cache.set(filePath, miss);
7591
7588
  return null;
7592
7589
  }
7593
7590
  const fingerprint = `${stats.dev}:${stats.ino}:${stats.size}`;
7594
7591
  const mtimeMs = stats.mtimeMs;
7595
- if (cache.current && cache.current.fingerprint === fingerprint && cache.current.mtimeMs === mtimeMs) {
7596
- return cache.current.enabledOverride;
7592
+ const cached2 = cache.get(filePath);
7593
+ if (cached2 && cached2.fingerprint === fingerprint && cached2.mtimeMs === mtimeMs) {
7594
+ return cached2.enabledOverride;
7597
7595
  }
7598
7596
  let parsedEnabled = null;
7599
7597
  try {
7600
- const raw = fs9.readFileSync(configFilePath(), "utf8");
7598
+ const raw = fs9.readFileSync(filePath, "utf8");
7601
7599
  const json = JSON.parse(raw);
7602
7600
  if (json && typeof json === "object") {
7603
7601
  const t2 = json.telemetry;
@@ -7608,9 +7606,27 @@ function readConfigOverride() {
7608
7606
  }
7609
7607
  } catch {
7610
7608
  }
7611
- cache.current = { mtimeMs, fingerprint, enabledOverride: parsedEnabled };
7609
+ cache.set(filePath, { mtimeMs, fingerprint, enabledOverride: parsedEnabled });
7612
7610
  return parsedEnabled;
7613
7611
  }
7612
+ function readPersistedConsent(cwd) {
7613
+ const globalPath = configFilePath("global");
7614
+ const projectPath = configFilePath("project", { cwd });
7615
+ const global2 = readConfigOverrideAt(globalPath);
7616
+ const project = projectPath === globalPath ? null : readConfigOverrideAt(projectPath);
7617
+ if (project === false && global2 === false) {
7618
+ return { enabled: false, detail: "config.json (project and global)" };
7619
+ }
7620
+ if (project === false) return { enabled: false, detail: "config.json (project)" };
7621
+ if (global2 === false) return { enabled: false, detail: "config.json (global)" };
7622
+ if (project === true || global2 === true) {
7623
+ return {
7624
+ enabled: true,
7625
+ detail: project === true ? "config.json (project)" : "config.json (global)"
7626
+ };
7627
+ }
7628
+ return null;
7629
+ }
7614
7630
  function parseFalsy(value) {
7615
7631
  if (value === void 0) return false;
7616
7632
  const v = value.trim().toLowerCase();
@@ -7620,7 +7636,7 @@ function isDoNotTrackSet(value) {
7620
7636
  if (value === void 0 || value.trim() === "") return false;
7621
7637
  return !parseFalsy(value);
7622
7638
  }
7623
- function getConsentState(env = process.env) {
7639
+ function getConsentState(env = process.env, cwd = process.cwd()) {
7624
7640
  if (isDoNotTrackSet(env.DO_NOT_TRACK)) {
7625
7641
  return {
7626
7642
  enabled: false,
@@ -7637,24 +7653,28 @@ function getConsentState(env = process.env) {
7637
7653
  if (sessionOverride !== null) {
7638
7654
  return { enabled: sessionOverride, source: { source: "session_override" } };
7639
7655
  }
7640
- const persisted = readConfigOverride();
7641
- if (persisted === false) {
7642
- return { enabled: false, source: { source: "config_file", detail: "config.json" } };
7643
- }
7644
- if (persisted === true) {
7645
- return { enabled: true, source: { source: "config_file", detail: "config.json" } };
7656
+ const persisted = readPersistedConsent(cwd);
7657
+ if (persisted !== null) {
7658
+ return {
7659
+ enabled: persisted.enabled,
7660
+ source: { source: "config_file", detail: persisted.detail }
7661
+ };
7646
7662
  }
7647
7663
  return { enabled: true, source: { source: "default" } };
7648
7664
  }
7649
- function isEnabled(env = process.env) {
7650
- return getConsentState(env).enabled;
7665
+ function isEnabled(env = process.env, cwd) {
7666
+ return getConsentState(env, cwd).enabled;
7651
7667
  }
7652
- function writeConsentFlag(enabled) {
7653
- updateConfig((config2) => {
7654
- const telemetryBlock = typeof config2.telemetry === "object" && config2.telemetry ? config2.telemetry : {};
7655
- config2.telemetry = { ...telemetryBlock, enabled };
7656
- });
7657
- cache.current = null;
7668
+ function writeConsentFlag(enabled, scope = "global", options = {}) {
7669
+ updateConfig(
7670
+ (config2) => {
7671
+ const telemetryBlock = typeof config2.telemetry === "object" && config2.telemetry ? config2.telemetry : {};
7672
+ config2.telemetry = { ...telemetryBlock, enabled };
7673
+ },
7674
+ scope,
7675
+ options
7676
+ );
7677
+ cache.clear();
7658
7678
  }
7659
7679
 
7660
7680
  // ../telemetry/src/notice.ts
@@ -7750,13 +7770,13 @@ async function shutdown(timeoutMs = SHORT_FLUSH_TIMEOUT_MS) {
7750
7770
  state = null;
7751
7771
  }
7752
7772
  }
7753
- function markEnabled() {
7754
- writeConsentFlag(true);
7773
+ function markEnabled(scope = "global") {
7774
+ writeConsentFlag(true, scope);
7755
7775
  }
7756
- async function markDisabled() {
7776
+ async function markDisabled(scope = "global") {
7757
7777
  try {
7758
7778
  const client2 = getConstructedClient();
7759
- writeConsentFlag(false);
7779
+ writeConsentFlag(false, scope);
7760
7780
  if (client2) {
7761
7781
  try {
7762
7782
  await raceDrain(client2, SHORT_FLUSH_TIMEOUT_MS);
@@ -10803,8 +10823,8 @@ Options:
10803
10823
  console.log("Feature flags (project overrides global):");
10804
10824
  const maxName = registryView.reduce((m, f) => Math.max(m, f.name.length), 0);
10805
10825
  for (const f of registryView) {
10806
- const scopeLabel2 = f.scope ? ` (${f.scope})` : "";
10807
- console.log(` ${f.name.padEnd(maxName, " ")} ${colorState(f.enabled)}${scopeLabel2}`);
10826
+ const scopeLabel3 = f.scope ? ` (${f.scope})` : "";
10827
+ console.log(` ${f.name.padEnd(maxName, " ")} ${colorState(f.enabled)}${scopeLabel3}`);
10808
10828
  console.log(` ${" ".repeat(maxName)} ${f.description}`);
10809
10829
  }
10810
10830
  }
@@ -12804,8 +12824,80 @@ async function unlink3(argv) {
12804
12824
 
12805
12825
  // ../argent-cli/src/telemetry.ts
12806
12826
  var import_picocolors5 = __toESM(require_picocolors(), 1);
12827
+
12828
+ // ../argent-cli/src/command-args.ts
12829
+ var UsageError = class extends Error {
12830
+ constructor(message) {
12831
+ super(message);
12832
+ this.name = "UsageError";
12833
+ }
12834
+ };
12835
+ function parseCommandArgs(argv, specs) {
12836
+ const positionals = [];
12837
+ const options = {};
12838
+ for (let i2 = 0; i2 < argv.length; i2++) {
12839
+ const tok = argv[i2];
12840
+ if (tok === "--") {
12841
+ positionals.push(...argv.slice(i2 + 1));
12842
+ break;
12843
+ }
12844
+ if (!tok.startsWith("--")) {
12845
+ positionals.push(tok);
12846
+ continue;
12847
+ }
12848
+ const eq = tok.indexOf("=");
12849
+ const name = eq === -1 ? tok.slice(2) : tok.slice(2, eq);
12850
+ const inlineValue = eq === -1 ? void 0 : tok.slice(eq + 1);
12851
+ const spec = specs[name];
12852
+ if (!spec) throw new UsageError(`Unknown flag "${tok}".`);
12853
+ if (spec.kind === "boolean") {
12854
+ if (inlineValue !== void 0) throw new UsageError(`--${name} does not take a value.`);
12855
+ options[name] = true;
12856
+ continue;
12857
+ }
12858
+ let value = inlineValue;
12859
+ if (value === void 0) {
12860
+ const next = argv[i2 + 1];
12861
+ if (next !== void 0 && !next.startsWith("--")) {
12862
+ value = next;
12863
+ i2 += 1;
12864
+ }
12865
+ }
12866
+ if (value === void 0 || value === "") {
12867
+ throw new UsageError(
12868
+ `--${name} requires a value${spec.choices ? ` (${spec.choices.join("|")})` : ""}.`
12869
+ );
12870
+ }
12871
+ if (spec.choices && !spec.choices.includes(value)) {
12872
+ throw new UsageError(
12873
+ `--${name} must be one of ${spec.choices.map((c2) => `"${c2}"`).join(", ")} (got "${value}").`
12874
+ );
12875
+ }
12876
+ options[name] = value;
12877
+ }
12878
+ return { positionals, options };
12879
+ }
12880
+
12881
+ // ../argent-cli/src/telemetry.ts
12882
+ var SCOPES = ["global", "project"];
12883
+ var TELEMETRY_OPTIONS = {
12884
+ scope: { kind: "value", choices: SCOPES }
12885
+ };
12807
12886
  async function telemetry(args) {
12808
12887
  const sub = args[0];
12888
+ let scope = "global";
12889
+ try {
12890
+ const { positionals, options } = parseCommandArgs(args.slice(1), TELEMETRY_OPTIONS);
12891
+ if (positionals.length > 0) {
12892
+ throw new UsageError(`Unexpected argument "${positionals[0]}".`);
12893
+ }
12894
+ if (options.scope !== void 0) scope = options.scope;
12895
+ } catch (err) {
12896
+ if (!(err instanceof UsageError)) throw err;
12897
+ console.error(`Error: ${err.message}`);
12898
+ printUsage3();
12899
+ process.exit(2);
12900
+ }
12809
12901
  init("cli");
12810
12902
  switch (sub) {
12811
12903
  case void 0:
@@ -12817,10 +12909,10 @@ async function telemetry(args) {
12817
12909
  await shutdown();
12818
12910
  return;
12819
12911
  case "enable":
12820
- await cmdEnable();
12912
+ await cmdEnable(scope);
12821
12913
  return;
12822
12914
  case "disable":
12823
- await cmdDisable();
12915
+ await cmdDisable(scope);
12824
12916
  return;
12825
12917
  case "--help":
12826
12918
  case "-h":
@@ -12835,37 +12927,64 @@ async function telemetry(args) {
12835
12927
  }
12836
12928
  function printUsage3() {
12837
12929
  console.log(`Usage:
12838
- argent telemetry status Show telemetry state and device id
12839
- argent telemetry enable Enable telemetry
12840
- argent telemetry disable Disable telemetry
12930
+ argent telemetry status Show telemetry state and device id
12931
+ argent telemetry enable [--scope global|project] Enable telemetry
12932
+ argent telemetry disable [--scope global|project] Disable telemetry
12933
+
12934
+ The default scope is global (~/.argent/config.json). \`--scope project\` writes
12935
+ <project-root>/.argent/config.json instead \u2014 commit it and telemetry stays off
12936
+ for everyone who clones the repository. \`false\` in either scope wins.
12841
12937
  `);
12842
12938
  }
12939
+ function scopeLabel2(scope) {
12940
+ return scope === "project" ? "project scope" : "global scope";
12941
+ }
12843
12942
  function printStatus() {
12844
12943
  const s = status();
12845
12944
  const idLabel = s.anonIdPrefix ? `${s.anonIdPrefix}...` : s.hasAnonIdOnDisk ? "present" : "not created";
12846
12945
  console.log("telemetry:");
12847
12946
  console.log(` state: ${s.enabled ? "enabled" : "disabled"}`);
12947
+ console.log(` source: ${describeSource(s.source)}`);
12848
12948
  console.log(` device id: ${idLabel}`);
12849
12949
  }
12850
- async function cmdEnable() {
12950
+ function describeSource(source) {
12951
+ switch (source.source) {
12952
+ case "env_do_not_track":
12953
+ case "env_argent_telemetry":
12954
+ return `environment (${source.detail ?? source.source})`;
12955
+ case "config_file":
12956
+ return source.detail ?? "config.json";
12957
+ case "session_override":
12958
+ return "this session";
12959
+ case "default":
12960
+ return "default (no opt-out set)";
12961
+ }
12962
+ }
12963
+ async function cmdEnable(scope) {
12851
12964
  const wasEnabled = isEnabled();
12852
- markEnabled();
12853
- if (wasEnabled) {
12854
- console.log(import_picocolors5.default.dim("Telemetry was already enabled."));
12965
+ markEnabled(scope);
12966
+ const nowEnabled = isEnabled();
12967
+ if (!nowEnabled) {
12968
+ console.log(
12969
+ import_picocolors5.default.yellow(
12970
+ `Telemetry set to enabled at ${scopeLabel2(scope)}, but it stays disabled: ${describeSource(status().source)} still opts out.`
12971
+ )
12972
+ );
12973
+ } else if (wasEnabled) {
12974
+ console.log(import_picocolors5.default.dim(`Telemetry was already enabled (written at ${scopeLabel2(scope)}).`));
12855
12975
  } else {
12856
- console.log(import_picocolors5.default.green("Telemetry enabled."));
12976
+ console.log(import_picocolors5.default.green(`Telemetry enabled (${scopeLabel2(scope)}).`));
12857
12977
  }
12858
12978
  await shutdown();
12859
12979
  }
12860
- async function cmdDisable() {
12980
+ async function cmdDisable(scope) {
12861
12981
  const wasEnabled = isEnabled();
12982
+ await markDisabled(scope);
12862
12983
  if (!wasEnabled) {
12863
- console.log(import_picocolors5.default.dim("Telemetry was already disabled."));
12864
- await shutdown();
12865
- return;
12984
+ console.log(import_picocolors5.default.dim(`Telemetry was already disabled (written at ${scopeLabel2(scope)}).`));
12985
+ } else {
12986
+ console.log(import_picocolors5.default.red(`Telemetry disabled (${scopeLabel2(scope)}).`));
12866
12987
  }
12867
- await markDisabled();
12868
- console.log(import_picocolors5.default.red("Telemetry disabled."));
12869
12988
  await shutdown();
12870
12989
  }
12871
12990
  export {
@@ -16428,7 +16428,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
16428
16428
  var SESSION_ID = randomUUID4();
16429
16429
  function readCliVersion() {
16430
16430
  if (true) {
16431
- return "0.22.1-next.6";
16431
+ return "0.22.1-next.7";
16432
16432
  }
16433
16433
  return "0.0.0";
16434
16434
  }
@@ -16806,32 +16806,30 @@ function resolveHostFingerprintAsync() {
16806
16806
 
16807
16807
  // ../telemetry/src/consent.ts
16808
16808
  import * as fs8 from "node:fs";
16809
- var cache = { current: null };
16809
+ var cache = /* @__PURE__ */ new Map();
16810
16810
  var sessionOverride = null;
16811
- function readConfigOverride() {
16811
+ function readConfigOverrideAt(filePath) {
16812
+ const miss = { mtimeMs: null, fingerprint: null, enabledOverride: null };
16812
16813
  let stats;
16813
16814
  try {
16814
- stats = fs8.lstatSync(configFilePath());
16815
- } catch (err) {
16816
- if (err.code === "ENOENT") {
16817
- cache.current = { mtimeMs: null, fingerprint: null, enabledOverride: null };
16818
- return null;
16819
- }
16820
- cache.current = { mtimeMs: null, fingerprint: null, enabledOverride: null };
16815
+ stats = fs8.lstatSync(filePath);
16816
+ } catch {
16817
+ cache.set(filePath, miss);
16821
16818
  return null;
16822
16819
  }
16823
16820
  if (!stats.isFile()) {
16824
- cache.current = { mtimeMs: null, fingerprint: null, enabledOverride: null };
16821
+ cache.set(filePath, miss);
16825
16822
  return null;
16826
16823
  }
16827
16824
  const fingerprint = `${stats.dev}:${stats.ino}:${stats.size}`;
16828
16825
  const mtimeMs = stats.mtimeMs;
16829
- if (cache.current && cache.current.fingerprint === fingerprint && cache.current.mtimeMs === mtimeMs) {
16830
- return cache.current.enabledOverride;
16826
+ const cached2 = cache.get(filePath);
16827
+ if (cached2 && cached2.fingerprint === fingerprint && cached2.mtimeMs === mtimeMs) {
16828
+ return cached2.enabledOverride;
16831
16829
  }
16832
16830
  let parsedEnabled = null;
16833
16831
  try {
16834
- const raw = fs8.readFileSync(configFilePath(), "utf8");
16832
+ const raw = fs8.readFileSync(filePath, "utf8");
16835
16833
  const json = JSON.parse(raw);
16836
16834
  if (json && typeof json === "object") {
16837
16835
  const t2 = json.telemetry;
@@ -16842,9 +16840,27 @@ function readConfigOverride() {
16842
16840
  }
16843
16841
  } catch {
16844
16842
  }
16845
- cache.current = { mtimeMs, fingerprint, enabledOverride: parsedEnabled };
16843
+ cache.set(filePath, { mtimeMs, fingerprint, enabledOverride: parsedEnabled });
16846
16844
  return parsedEnabled;
16847
16845
  }
16846
+ function readPersistedConsent(cwd) {
16847
+ const globalPath = configFilePath("global");
16848
+ const projectPath = configFilePath("project", { cwd });
16849
+ const global2 = readConfigOverrideAt(globalPath);
16850
+ const project = projectPath === globalPath ? null : readConfigOverrideAt(projectPath);
16851
+ if (project === false && global2 === false) {
16852
+ return { enabled: false, detail: "config.json (project and global)" };
16853
+ }
16854
+ if (project === false) return { enabled: false, detail: "config.json (project)" };
16855
+ if (global2 === false) return { enabled: false, detail: "config.json (global)" };
16856
+ if (project === true || global2 === true) {
16857
+ return {
16858
+ enabled: true,
16859
+ detail: project === true ? "config.json (project)" : "config.json (global)"
16860
+ };
16861
+ }
16862
+ return null;
16863
+ }
16848
16864
  function parseFalsy(value) {
16849
16865
  if (value === void 0) return false;
16850
16866
  const v = value.trim().toLowerCase();
@@ -16854,7 +16870,7 @@ function isDoNotTrackSet(value) {
16854
16870
  if (value === void 0 || value.trim() === "") return false;
16855
16871
  return !parseFalsy(value);
16856
16872
  }
16857
- function getConsentState(env = process.env) {
16873
+ function getConsentState(env = process.env, cwd = process.cwd()) {
16858
16874
  if (isDoNotTrackSet(env.DO_NOT_TRACK)) {
16859
16875
  return {
16860
16876
  enabled: false,
@@ -16871,24 +16887,28 @@ function getConsentState(env = process.env) {
16871
16887
  if (sessionOverride !== null) {
16872
16888
  return { enabled: sessionOverride, source: { source: "session_override" } };
16873
16889
  }
16874
- const persisted = readConfigOverride();
16875
- if (persisted === false) {
16876
- return { enabled: false, source: { source: "config_file", detail: "config.json" } };
16877
- }
16878
- if (persisted === true) {
16879
- return { enabled: true, source: { source: "config_file", detail: "config.json" } };
16890
+ const persisted = readPersistedConsent(cwd);
16891
+ if (persisted !== null) {
16892
+ return {
16893
+ enabled: persisted.enabled,
16894
+ source: { source: "config_file", detail: persisted.detail }
16895
+ };
16880
16896
  }
16881
16897
  return { enabled: true, source: { source: "default" } };
16882
16898
  }
16883
- function isEnabled(env = process.env) {
16884
- return getConsentState(env).enabled;
16899
+ function isEnabled(env = process.env, cwd) {
16900
+ return getConsentState(env, cwd).enabled;
16885
16901
  }
16886
- function writeConsentFlag(enabled) {
16887
- updateConfig((config) => {
16888
- const telemetryBlock = typeof config.telemetry === "object" && config.telemetry ? config.telemetry : {};
16889
- config.telemetry = { ...telemetryBlock, enabled };
16890
- });
16891
- cache.current = null;
16902
+ function writeConsentFlag(enabled, scope = "global", options = {}) {
16903
+ updateConfig(
16904
+ (config) => {
16905
+ const telemetryBlock = typeof config.telemetry === "object" && config.telemetry ? config.telemetry : {};
16906
+ config.telemetry = { ...telemetryBlock, enabled };
16907
+ },
16908
+ scope,
16909
+ options
16910
+ );
16911
+ cache.clear();
16892
16912
  }
16893
16913
  function setSessionConsentOverride(enabled) {
16894
16914
  sessionOverride = enabled;
@@ -22455,6 +22475,18 @@ async function init2(args) {
22455
22475
  }
22456
22476
  tel.installMode = modeFromFlags ?? await promptInstallMode(recordedMode ?? "global");
22457
22477
  track("installation:install_mode_decision", { install_mode: tel.installMode });
22478
+ let wroteProjectTelemetryOptOut = false;
22479
+ if (parsed.noTelemetry && tel.installMode === "local") {
22480
+ try {
22481
+ writeConsentFlag(false, "project", { cwd: initProjectRoot });
22482
+ wroteProjectTelemetryOptOut = true;
22483
+ log.info(
22484
+ `${import_picocolors10.default.bold("Telemetry")} ${import_picocolors10.default.dim("also disabled for this project \u2014")} ${import_picocolors10.default.cyan(".argent/config.json")} ${import_picocolors10.default.dim("(commit it so the opt-out applies to every clone).")}`
22485
+ );
22486
+ } catch (err) {
22487
+ log.warn(`Could not write the project telemetry opt-out: ${err}`);
22488
+ }
22489
+ }
22458
22490
  version = await runInstall({
22459
22491
  installMode: tel.installMode,
22460
22492
  fromTar: parsed.fromTar,
@@ -22582,7 +22614,8 @@ async function init2(args) {
22582
22614
  scope,
22583
22615
  allowlistEnabled: allowlist.enabled,
22584
22616
  skillsMethod,
22585
- copiedRules: copyResults.length > 0
22617
+ copiedRules: copyResults.length > 0,
22618
+ wroteProjectTelemetryOptOut
22586
22619
  });
22587
22620
  note(
22588
22621
  [
@@ -22620,7 +22653,8 @@ function printSummary({
22620
22653
  scope,
22621
22654
  allowlistEnabled,
22622
22655
  skillsMethod,
22623
- copiedRules
22656
+ copiedRules,
22657
+ wroteProjectTelemetryOptOut
22624
22658
  }) {
22625
22659
  const summaryLines = [
22626
22660
  `${import_picocolors10.default.green("Install mode")} ${installMode === "local" ? "local (devDependency)" : "global"}`,
@@ -22638,7 +22672,7 @@ function printSummary({
22638
22672
  `${import_picocolors10.default.bold("Commit")} so your team shares the same setup:`,
22639
22673
  ` ${import_picocolors10.default.cyan("package.json")} + your lockfile`,
22640
22674
  ` the written MCP config (.mcp.json, .cursor/mcp.json, \u2026)`,
22641
- ` ${import_picocolors10.default.cyan(".argent/install.json")}, and the skills/rules/agents files`,
22675
+ ` ${import_picocolors10.default.cyan(".argent/install.json")}${wroteProjectTelemetryOptOut ? ` + ${import_picocolors10.default.cyan(".argent/config.json")}` : ""}, and the skills/rules/agents files`,
22642
22676
  "",
22643
22677
  `Teammates then get argent on ${import_picocolors10.default.cyan("npm install")} \u2014 no global install, no ${import_picocolors10.default.cyan("argent init")}.`,
22644
22678
  import_picocolors10.default.dim(
@@ -17142,8 +17142,8 @@ function asStringArray(raw) {
17142
17142
  var CONFIG_SCHEMA = [
17143
17143
  {
17144
17144
  key: "telemetry.enabled",
17145
- description: "Whether anonymous opt-out telemetry is enabled (on by default; environment opt-outs like DO_NOT_TRACK are not reflected here \u2014 `argent telemetry status` shows effective consent).",
17146
- scopes: ["global"],
17145
+ description: "Whether anonymous opt-out telemetry is enabled (on by default; environment opt-outs like DO_NOT_TRACK are not reflected here \u2014 `argent telemetry status` shows effective consent). `false` in either scope wins, so a committed project opt-out holds for every teammate.",
17146
+ scopes: ["project", "global"],
17147
17147
  parse: asBoolean,
17148
17148
  merge: "prioritize-restrictive",
17149
17149
  // Opt-out: consent.ts reads an unstored value as enabled, so the config
@@ -18177,32 +18177,30 @@ var DYLIB_TVOS_DIR = path11.join(DYLIB_DIR, "tvos");
18177
18177
 
18178
18178
  // ../telemetry/src/consent.ts
18179
18179
  import * as fs8 from "node:fs";
18180
- var cache = { current: null };
18180
+ var cache = /* @__PURE__ */ new Map();
18181
18181
  var sessionOverride = null;
18182
- function readConfigOverride() {
18182
+ function readConfigOverrideAt(filePath) {
18183
+ const miss = { mtimeMs: null, fingerprint: null, enabledOverride: null };
18183
18184
  let stats;
18184
18185
  try {
18185
- stats = fs8.lstatSync(configFilePath());
18186
- } catch (err) {
18187
- if (err.code === "ENOENT") {
18188
- cache.current = { mtimeMs: null, fingerprint: null, enabledOverride: null };
18189
- return null;
18190
- }
18191
- cache.current = { mtimeMs: null, fingerprint: null, enabledOverride: null };
18186
+ stats = fs8.lstatSync(filePath);
18187
+ } catch {
18188
+ cache.set(filePath, miss);
18192
18189
  return null;
18193
18190
  }
18194
18191
  if (!stats.isFile()) {
18195
- cache.current = { mtimeMs: null, fingerprint: null, enabledOverride: null };
18192
+ cache.set(filePath, miss);
18196
18193
  return null;
18197
18194
  }
18198
18195
  const fingerprint = `${stats.dev}:${stats.ino}:${stats.size}`;
18199
18196
  const mtimeMs = stats.mtimeMs;
18200
- if (cache.current && cache.current.fingerprint === fingerprint && cache.current.mtimeMs === mtimeMs) {
18201
- return cache.current.enabledOverride;
18197
+ const cached2 = cache.get(filePath);
18198
+ if (cached2 && cached2.fingerprint === fingerprint && cached2.mtimeMs === mtimeMs) {
18199
+ return cached2.enabledOverride;
18202
18200
  }
18203
18201
  let parsedEnabled = null;
18204
18202
  try {
18205
- const raw = fs8.readFileSync(configFilePath(), "utf8");
18203
+ const raw = fs8.readFileSync(filePath, "utf8");
18206
18204
  const json = JSON.parse(raw);
18207
18205
  if (json && typeof json === "object") {
18208
18206
  const t = json.telemetry;
@@ -18213,9 +18211,27 @@ function readConfigOverride() {
18213
18211
  }
18214
18212
  } catch {
18215
18213
  }
18216
- cache.current = { mtimeMs, fingerprint, enabledOverride: parsedEnabled };
18214
+ cache.set(filePath, { mtimeMs, fingerprint, enabledOverride: parsedEnabled });
18217
18215
  return parsedEnabled;
18218
18216
  }
18217
+ function readPersistedConsent(cwd) {
18218
+ const globalPath = configFilePath("global");
18219
+ const projectPath = configFilePath("project", { cwd });
18220
+ const global = readConfigOverrideAt(globalPath);
18221
+ const project = projectPath === globalPath ? null : readConfigOverrideAt(projectPath);
18222
+ if (project === false && global === false) {
18223
+ return { enabled: false, detail: "config.json (project and global)" };
18224
+ }
18225
+ if (project === false) return { enabled: false, detail: "config.json (project)" };
18226
+ if (global === false) return { enabled: false, detail: "config.json (global)" };
18227
+ if (project === true || global === true) {
18228
+ return {
18229
+ enabled: true,
18230
+ detail: project === true ? "config.json (project)" : "config.json (global)"
18231
+ };
18232
+ }
18233
+ return null;
18234
+ }
18219
18235
  function parseFalsy(value) {
18220
18236
  if (value === void 0) return false;
18221
18237
  const v = value.trim().toLowerCase();
@@ -18225,7 +18241,7 @@ function isDoNotTrackSet(value) {
18225
18241
  if (value === void 0 || value.trim() === "") return false;
18226
18242
  return !parseFalsy(value);
18227
18243
  }
18228
- function getConsentState(env = process.env) {
18244
+ function getConsentState(env = process.env, cwd = process.cwd()) {
18229
18245
  if (isDoNotTrackSet(env.DO_NOT_TRACK)) {
18230
18246
  return {
18231
18247
  enabled: false,
@@ -18242,17 +18258,17 @@ function getConsentState(env = process.env) {
18242
18258
  if (sessionOverride !== null) {
18243
18259
  return { enabled: sessionOverride, source: { source: "session_override" } };
18244
18260
  }
18245
- const persisted = readConfigOverride();
18246
- if (persisted === false) {
18247
- return { enabled: false, source: { source: "config_file", detail: "config.json" } };
18248
- }
18249
- if (persisted === true) {
18250
- return { enabled: true, source: { source: "config_file", detail: "config.json" } };
18261
+ const persisted = readPersistedConsent(cwd);
18262
+ if (persisted !== null) {
18263
+ return {
18264
+ enabled: persisted.enabled,
18265
+ source: { source: "config_file", detail: persisted.detail }
18266
+ };
18251
18267
  }
18252
18268
  return { enabled: true, source: { source: "default" } };
18253
18269
  }
18254
- function isEnabled(env = process.env) {
18255
- return getConsentState(env).enabled;
18270
+ function isEnabled(env = process.env, cwd) {
18271
+ return getConsentState(env, cwd).enabled;
18256
18272
  }
18257
18273
 
18258
18274
  // ../telemetry/src/notice.ts
@@ -92132,8 +92132,8 @@ function asStringArray(raw) {
92132
92132
  var CONFIG_SCHEMA = [
92133
92133
  {
92134
92134
  key: "telemetry.enabled",
92135
- description: "Whether anonymous opt-out telemetry is enabled (on by default; environment opt-outs like DO_NOT_TRACK are not reflected here \u2014 `argent telemetry status` shows effective consent).",
92136
- scopes: ["global"],
92135
+ description: "Whether anonymous opt-out telemetry is enabled (on by default; environment opt-outs like DO_NOT_TRACK are not reflected here \u2014 `argent telemetry status` shows effective consent). `false` in either scope wins, so a committed project opt-out holds for every teammate.",
92136
+ scopes: ["project", "global"],
92137
92137
  parse: asBoolean,
92138
92138
  merge: "prioritize-restrictive",
92139
92139
  // Opt-out: consent.ts reads an unstored value as enabled, so the config
@@ -95734,7 +95734,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
95734
95734
  var SESSION_ID = (0, import_node_crypto3.randomUUID)();
95735
95735
  function readCliVersion() {
95736
95736
  if (true) {
95737
- return "0.22.1-next.6";
95737
+ return "0.22.1-next.7";
95738
95738
  }
95739
95739
  return "0.0.0";
95740
95740
  }
@@ -96201,32 +96201,30 @@ function resolveHostFingerprintAsync() {
96201
96201
 
96202
96202
  // ../telemetry/src/consent.ts
96203
96203
  var fs8 = __toESM(require("node:fs"));
96204
- var cache = { current: null };
96204
+ var cache = /* @__PURE__ */ new Map();
96205
96205
  var sessionOverride = null;
96206
- function readConfigOverride() {
96206
+ function readConfigOverrideAt(filePath) {
96207
+ const miss = { mtimeMs: null, fingerprint: null, enabledOverride: null };
96207
96208
  let stats;
96208
96209
  try {
96209
- stats = fs8.lstatSync(configFilePath());
96210
- } catch (err) {
96211
- if (err.code === "ENOENT") {
96212
- cache.current = { mtimeMs: null, fingerprint: null, enabledOverride: null };
96213
- return null;
96214
- }
96215
- cache.current = { mtimeMs: null, fingerprint: null, enabledOverride: null };
96210
+ stats = fs8.lstatSync(filePath);
96211
+ } catch {
96212
+ cache.set(filePath, miss);
96216
96213
  return null;
96217
96214
  }
96218
96215
  if (!stats.isFile()) {
96219
- cache.current = { mtimeMs: null, fingerprint: null, enabledOverride: null };
96216
+ cache.set(filePath, miss);
96220
96217
  return null;
96221
96218
  }
96222
96219
  const fingerprint = `${stats.dev}:${stats.ino}:${stats.size}`;
96223
96220
  const mtimeMs = stats.mtimeMs;
96224
- if (cache.current && cache.current.fingerprint === fingerprint && cache.current.mtimeMs === mtimeMs) {
96225
- return cache.current.enabledOverride;
96221
+ const cached3 = cache.get(filePath);
96222
+ if (cached3 && cached3.fingerprint === fingerprint && cached3.mtimeMs === mtimeMs) {
96223
+ return cached3.enabledOverride;
96226
96224
  }
96227
96225
  let parsedEnabled = null;
96228
96226
  try {
96229
- const raw = fs8.readFileSync(configFilePath(), "utf8");
96227
+ const raw = fs8.readFileSync(filePath, "utf8");
96230
96228
  const json2 = JSON.parse(raw);
96231
96229
  if (json2 && typeof json2 === "object") {
96232
96230
  const t = json2.telemetry;
@@ -96237,9 +96235,27 @@ function readConfigOverride() {
96237
96235
  }
96238
96236
  } catch {
96239
96237
  }
96240
- cache.current = { mtimeMs, fingerprint, enabledOverride: parsedEnabled };
96238
+ cache.set(filePath, { mtimeMs, fingerprint, enabledOverride: parsedEnabled });
96241
96239
  return parsedEnabled;
96242
96240
  }
96241
+ function readPersistedConsent(cwd) {
96242
+ const globalPath = configFilePath("global");
96243
+ const projectPath = configFilePath("project", { cwd });
96244
+ const global2 = readConfigOverrideAt(globalPath);
96245
+ const project = projectPath === globalPath ? null : readConfigOverrideAt(projectPath);
96246
+ if (project === false && global2 === false) {
96247
+ return { enabled: false, detail: "config.json (project and global)" };
96248
+ }
96249
+ if (project === false) return { enabled: false, detail: "config.json (project)" };
96250
+ if (global2 === false) return { enabled: false, detail: "config.json (global)" };
96251
+ if (project === true || global2 === true) {
96252
+ return {
96253
+ enabled: true,
96254
+ detail: project === true ? "config.json (project)" : "config.json (global)"
96255
+ };
96256
+ }
96257
+ return null;
96258
+ }
96243
96259
  function parseFalsy(value) {
96244
96260
  if (value === void 0) return false;
96245
96261
  const v = value.trim().toLowerCase();
@@ -96249,7 +96265,7 @@ function isDoNotTrackSet(value) {
96249
96265
  if (value === void 0 || value.trim() === "") return false;
96250
96266
  return !parseFalsy(value);
96251
96267
  }
96252
- function getConsentState(env = process.env) {
96268
+ function getConsentState(env = process.env, cwd = process.cwd()) {
96253
96269
  if (isDoNotTrackSet(env.DO_NOT_TRACK)) {
96254
96270
  return {
96255
96271
  enabled: false,
@@ -96266,17 +96282,17 @@ function getConsentState(env = process.env) {
96266
96282
  if (sessionOverride !== null) {
96267
96283
  return { enabled: sessionOverride, source: { source: "session_override" } };
96268
96284
  }
96269
- const persisted = readConfigOverride();
96270
- if (persisted === false) {
96271
- return { enabled: false, source: { source: "config_file", detail: "config.json" } };
96272
- }
96273
- if (persisted === true) {
96274
- return { enabled: true, source: { source: "config_file", detail: "config.json" } };
96285
+ const persisted = readPersistedConsent(cwd);
96286
+ if (persisted !== null) {
96287
+ return {
96288
+ enabled: persisted.enabled,
96289
+ source: { source: "config_file", detail: persisted.detail }
96290
+ };
96275
96291
  }
96276
96292
  return { enabled: true, source: { source: "default" } };
96277
96293
  }
96278
- function isEnabled(env = process.env) {
96279
- return getConsentState(env).enabled;
96294
+ function isEnabled(env = process.env, cwd) {
96295
+ return getConsentState(env, cwd).enabled;
96280
96296
  }
96281
96297
 
96282
96298
  // ../telemetry/src/notice.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swmansion/argent",
3
- "version": "0.22.1-next.6",
3
+ "version": "0.22.1-next.7",
4
4
  "mcpName": "io.github.software-mansion/argent",
5
5
  "description": "MCP server for iOS Simulator and Android Emulator control",
6
6
  "license": "Apache-2.0",