iteration-cli 0.15.0 → 0.16.1

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.js CHANGED
@@ -10,7 +10,6 @@ import { spawnSync } from "node:child_process";
10
10
  import { promises as fs24 } from "node:fs";
11
11
  import os11 from "node:os";
12
12
  import path30 from "node:path";
13
- import { createInterface as createInterface2 } from "node:readline/promises";
14
13
  import { parseArgs } from "node:util";
15
14
 
16
15
  // ../trace-vault/packages/cli/dist/index.js
@@ -1163,7 +1162,7 @@ function putProp(target, key, value) {
1163
1162
  else
1164
1163
  target[key] = value;
1165
1164
  }
1166
- function mirrorShape(target, source, keys, wrap) {
1165
+ function mirrorShape(target, source, keys, wrap2) {
1167
1166
  const raw = sourceShape(source);
1168
1167
  for (const key of keys) {
1169
1168
  const desc = Object.getOwnPropertyDescriptor(raw, key);
@@ -1172,10 +1171,10 @@ function mirrorShape(target, source, keys, wrap) {
1172
1171
  if (desc.get) {
1173
1172
  deferProp(target, key, () => {
1174
1173
  const value = source._zod.def.shape[key];
1175
- return wrap ? wrap(value, key) : value;
1174
+ return wrap2 ? wrap2(value, key) : value;
1176
1175
  });
1177
1176
  } else
1178
- putProp(target, key, wrap ? wrap(desc.value, key) : desc.value);
1177
+ putProp(target, key, wrap2 ? wrap2(desc.value, key) : desc.value);
1179
1178
  }
1180
1179
  }
1181
1180
  function mirrorProps(target, source) {
@@ -2015,9 +2014,9 @@ function formatError(error22, mapper = (issue22) => issue22.message) {
2015
2014
  let i = 0;
2016
2015
  while (i < fullpath.length) {
2017
2016
  const el = fullpath[i];
2018
- const terminal = i === fullpath.length - 1;
2017
+ const terminal2 = i === fullpath.length - 1;
2019
2018
  if (el === "_errors") {
2020
- if (terminal)
2019
+ if (terminal2)
2021
2020
  curr._errors.push(mapper(issue22));
2022
2021
  i++;
2023
2022
  continue;
@@ -2031,7 +2030,7 @@ function formatError(error22, mapper = (issue22) => issue22.message) {
2031
2030
  });
2032
2031
  }
2033
2032
  const node22 = curr[el];
2034
- if (terminal) {
2033
+ if (terminal2) {
2035
2034
  node22._errors.push(mapper(issue22));
2036
2035
  }
2037
2036
  curr = node22;
@@ -7890,9 +7889,9 @@ var ClaudeAccountIndex = class {
7890
7889
  add(map, session, id, record32) {
7891
7890
  if (id === null) return;
7892
7891
  const key = this.key(session, id);
7893
- const rows = map.get(key) ?? [];
7894
- rows.push(record32);
7895
- map.set(key, rows);
7892
+ const rows2 = map.get(key) ?? [];
7893
+ rows2.push(record32);
7894
+ map.set(key, rows2);
7896
7895
  }
7897
7896
  get(map, session, id) {
7898
7897
  return id ? map.get(this.key(session, id)) ?? [] : [];
@@ -7968,20 +7967,25 @@ var exportSchema = object({
7968
7967
  });
7969
7968
  var uuid3 = uuid2();
7970
7969
  var identifier2 = string2().regex(/^[A-Za-z0-9_:./-]{1,255}$/);
7970
+ function consoleWriter(line, level) {
7971
+ if (level === "info") console.info(line);
7972
+ else console.error(line);
7973
+ }
7971
7974
  var loggingContext = () => ({});
7972
- function configureCollectorLogging(context) {
7973
- loggingContext = context;
7975
+ var logWriter = consoleWriter;
7976
+ function configureCollectorLogging(context2, write = consoleWriter) {
7977
+ loggingContext = context2;
7978
+ logWriter = write;
7974
7979
  }
7975
7980
  function writeLog(line, level) {
7976
- if (level === "info") console.info(line);
7977
- else console.error(line);
7981
+ logWriter(line, level);
7978
7982
  }
7979
- function createLogger(context, write = writeLog) {
7983
+ function createLogger(context2, write = writeLog) {
7980
7984
  return (entry) => {
7981
7985
  write(
7982
7986
  JSON.stringify({
7983
7987
  ...entry,
7984
- ...context,
7988
+ ...context2,
7985
7989
  at: (/* @__PURE__ */ new Date()).toISOString(),
7986
7990
  pid: process.pid,
7987
7991
  ...loggingContext()
@@ -8380,11 +8384,11 @@ var SecretLintRule = class {
8380
8384
  ruleReportHandle;
8381
8385
  ruleCreator;
8382
8386
  descriptorRule;
8383
- constructor({ descriptorRule, context }) {
8387
+ constructor({ descriptorRule, context: context2 }) {
8384
8388
  this.descriptorRule = descriptorRule;
8385
8389
  this.ruleCreator = descriptorRule.rule;
8386
8390
  const ruleCreatorOptions = descriptorRule.options || {};
8387
- this.ruleReportHandle = this.ruleCreator.create(context, ruleCreatorOptions);
8391
+ this.ruleReportHandle = this.ruleCreator.create(context2, ruleCreatorOptions);
8388
8392
  }
8389
8393
  allowMessageIds() {
8390
8394
  if (!this.descriptorRule.allowMessageIds) {
@@ -8552,7 +8556,7 @@ var createRunningEvents = () => {
8552
8556
  runLint(options) {
8553
8557
  return contextEvents.emit(LINT_HANDLE, options);
8554
8558
  },
8555
- registerRule({ descriptorRule, context }) {
8559
+ registerRule({ descriptorRule, context: context2 }) {
8556
8560
  if (registerSet.has(descriptorRule.id)) {
8557
8561
  throw new Error(`rule.id:${descriptorRule.id} is already registered.
8558
8562
 
@@ -8562,7 +8566,7 @@ Duplicated rule.id is something wrong in .secretlintrc.
8562
8566
  registerSet.add(descriptorRule.id);
8563
8567
  const rule = new SecretLintRule({
8564
8568
  descriptorRule,
8565
- context
8569
+ context: context2
8566
8570
  });
8567
8571
  rules2.push(rule);
8568
8572
  contextEvents.on(LINT_HANDLE, async ({ sourceCode }) => {
@@ -8579,9 +8583,9 @@ Duplicated rule.id is something wrong in .secretlintrc.
8579
8583
  });
8580
8584
  });
8581
8585
  },
8582
- registerRulePreset({ descriptorRulePreset, context }) {
8586
+ registerRulePreset({ descriptorRulePreset, context: context2 }) {
8583
8587
  const rulePresetCreatorOptions = descriptorRulePreset.options || [];
8584
- descriptorRulePreset.rule.create(context, rulePresetCreatorOptions);
8588
+ descriptorRulePreset.rule.create(context2, rulePresetCreatorOptions);
8585
8589
  },
8586
8590
  isRegistered(ruleId) {
8587
8591
  return registerSet.has(ruleId);
@@ -8604,7 +8608,7 @@ var createRulePresetContext = ({ configRulePreset, sourceCode, runningEvents, co
8604
8608
  const descriptorRuleDisabled = descriptorRule ? descriptorRule.disabled : void 0;
8605
8609
  const descriptorRuleSeverity = descriptorRule ? descriptorRule.severity : void 0;
8606
8610
  const descriptorAllowMessageIds = descriptorRule ? descriptorRule.allowMessageIds : void 0;
8607
- const context = createRuleContext({
8611
+ const context2 = createRuleContext({
8608
8612
  // rule id is a single rule in a preset
8609
8613
  ruleId: rule.meta.id,
8610
8614
  // parent rule id is rule preset id
@@ -8631,7 +8635,7 @@ var createRulePresetContext = ({ configRulePreset, sourceCode, runningEvents, co
8631
8635
  allowMessageIds: descriptorAllowMessageIds,
8632
8636
  severity: descriptorRuleSeverity
8633
8637
  },
8634
- context
8638
+ context: context2
8635
8639
  });
8636
8640
  }
8637
8641
  };
@@ -8841,7 +8845,7 @@ var registerRule = ({ sourceCode, config: config22, descriptorRule, contextEvent
8841
8845
  debug("registerRule %s", ruleId);
8842
8846
  const sharedOptionsWithDefault = config22.sharedOptions ?? {};
8843
8847
  if (isRulePreset(descriptorRule)) {
8844
- const context = createRulePresetContext({
8848
+ const context2 = createRulePresetContext({
8845
8849
  configRulePreset: descriptorRule,
8846
8850
  sourceCode,
8847
8851
  contextEvents,
@@ -8851,11 +8855,11 @@ var registerRule = ({ sourceCode, config: config22, descriptorRule, contextEvent
8851
8855
  });
8852
8856
  runningEvents.registerRulePreset({
8853
8857
  descriptorRulePreset: descriptorRule,
8854
- context
8858
+ context: context2
8855
8859
  });
8856
8860
  return;
8857
8861
  } else if (isRule(descriptorRule)) {
8858
- const context = createRuleContext({
8862
+ const context2 = createRuleContext({
8859
8863
  ruleId,
8860
8864
  severity: descriptorRule.severity,
8861
8865
  meta: descriptorRule.rule.meta,
@@ -8866,7 +8870,7 @@ var registerRule = ({ sourceCode, config: config22, descriptorRule, contextEvent
8866
8870
  });
8867
8871
  runningEvents.registerRule({
8868
8872
  descriptorRule,
8869
- context
8873
+ context: context2
8870
8874
  });
8871
8875
  return;
8872
8876
  }
@@ -10569,7 +10573,7 @@ var messages$r = {
10569
10573
  ja: (props) => `AWS Access Key Id: ${props.ID} \u304C\u307F\u3064\u304B\u308A\u307E\u3057\u305F`
10570
10574
  }
10571
10575
  };
10572
- var reportAWSAccessKey = ({ t, source, context, options }) => {
10576
+ var reportAWSAccessKey = ({ t, source, context: context2, options }) => {
10573
10577
  const AWSAccessKeyIDPattern = /\b(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}\b/g;
10574
10578
  const results = source.content.matchAll(AWSAccessKeyIDPattern);
10575
10579
  for (const result of results) {
@@ -10583,7 +10587,7 @@ var reportAWSAccessKey = ({ t, source, context, options }) => {
10583
10587
  if (allowedResults.length > 0) {
10584
10588
  continue;
10585
10589
  }
10586
- context.report({
10590
+ context2.report({
10587
10591
  message: t("AWSAccessKeyID", {
10588
10592
  ID: match
10589
10593
  }),
@@ -10591,7 +10595,7 @@ var reportAWSAccessKey = ({ t, source, context, options }) => {
10591
10595
  });
10592
10596
  }
10593
10597
  };
10594
- var reportAWSSecretAccessKey = ({ t, source, context, options }) => {
10598
+ var reportAWSSecretAccessKey = ({ t, source, context: context2, options }) => {
10595
10599
  const AWS = "(?:AWS|aws|Aws)?_?";
10596
10600
  const QUOTE = `["']?`;
10597
10601
  const CONNECT = "\\s*(?::|=>|=)\\s*";
@@ -10608,7 +10612,7 @@ var reportAWSSecretAccessKey = ({ t, source, context, options }) => {
10608
10612
  if (allowedResults.length > 0) {
10609
10613
  continue;
10610
10614
  }
10611
- context.report({
10615
+ context2.report({
10612
10616
  message: t("AWSSecretAccessKey", {
10613
10617
  KEY: match
10614
10618
  }),
@@ -10616,7 +10620,7 @@ var reportAWSSecretAccessKey = ({ t, source, context, options }) => {
10616
10620
  });
10617
10621
  }
10618
10622
  };
10619
- var reportAWSAccountID = ({ t, source, context, options }) => {
10623
+ var reportAWSAccountID = ({ t, source, context: context2, options }) => {
10620
10624
  const AWS = "(AWS|aws|Aws)?_?";
10621
10625
  const QUOTE = `("|')?`;
10622
10626
  const CONNECT = "\\s*(:|=>|=)\\s*";
@@ -10630,7 +10634,7 @@ var reportAWSAccountID = ({ t, source, context, options }) => {
10630
10634
  if (allowedResults.length > 0) {
10631
10635
  continue;
10632
10636
  }
10633
- context.report({
10637
+ context2.report({
10634
10638
  message: t("AWSAccountID", {
10635
10639
  ID: match
10636
10640
  }),
@@ -10649,19 +10653,19 @@ var creator$s = {
10649
10653
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-aws/README.md"
10650
10654
  }
10651
10655
  },
10652
- create(context, options) {
10656
+ create(context2, options) {
10653
10657
  const normalizedOptions = {
10654
10658
  allows: options.allows || [],
10655
10659
  enableIDScanRule: options.enableIDScanRule ?? false
10656
10660
  };
10657
- const t = context.createTranslator(messages$r);
10661
+ const t = context2.createTranslator(messages$r);
10658
10662
  return {
10659
10663
  file(source) {
10660
10664
  if (normalizedOptions.enableIDScanRule) {
10661
- reportAWSAccessKey({ t, source, context, options: normalizedOptions });
10662
- reportAWSAccountID({ t, source, context, options: normalizedOptions });
10665
+ reportAWSAccessKey({ t, source, context: context2, options: normalizedOptions });
10666
+ reportAWSAccountID({ t, source, context: context2, options: normalizedOptions });
10663
10667
  }
10664
- reportAWSSecretAccessKey({ t, source, context, options: normalizedOptions });
10668
+ reportAWSSecretAccessKey({ t, source, context: context2, options: normalizedOptions });
10665
10669
  }
10666
10670
  };
10667
10671
  }
@@ -10862,7 +10866,7 @@ async function verifyPkcs12Mac(pfxBytes, password) {
10862
10866
  }
10863
10867
  }
10864
10868
  var GCP_SERVICE_ACCOUNT_P12_PASSWORD = "notasecret";
10865
- async function reportIfFoundPrivateKeyP12Format({ source, context, t }) {
10869
+ async function reportIfFoundPrivateKeyP12Format({ source, context: context2, t }) {
10866
10870
  if (!source.filePath) {
10867
10871
  return;
10868
10872
  }
@@ -10874,7 +10878,7 @@ async function reportIfFoundPrivateKeyP12Format({ source, context, t }) {
10874
10878
  if (!isGcpServiceAccountP12) {
10875
10879
  return;
10876
10880
  }
10877
- context.report({
10881
+ context2.report({
10878
10882
  message: t("PrivateKeyP12", {
10879
10883
  FILE_NAME: path172.basename(source.filePath)
10880
10884
  }),
@@ -10893,7 +10897,7 @@ var messages$q = {
10893
10897
  ja: (props) => `GCP\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u79D8\u5BC6\u9375(json): ${props.FILE_NAME} \u304C\u307F\u3064\u304B\u308A\u307E\u3057\u305F`
10894
10898
  }
10895
10899
  };
10896
- function reportIfFoundPrivateKeyJSONFormat({ source, context, t }) {
10900
+ function reportIfFoundPrivateKeyJSONFormat({ source, context: context2, t }) {
10897
10901
  try {
10898
10902
  const credentialObject = JSON.parse(source.content);
10899
10903
  const PRIVATE_KEY_PATTERN = /-----BEGIN\s?(DSA|RSA|EC|PGP|OPENSSH)?\s?PRIVATE KEY/gm;
@@ -10901,7 +10905,7 @@ function reportIfFoundPrivateKeyJSONFormat({ source, context, t }) {
10901
10905
  if (!isGCPServiceAccountPrivateKeyJSON) {
10902
10906
  return;
10903
10907
  }
10904
- context.report({
10908
+ context2.report({
10905
10909
  message: t("PrivateKeyJSON", {
10906
10910
  FILE_NAME: source.filePath ? path3.basename(source.filePath) : ""
10907
10911
  }),
@@ -10921,17 +10925,17 @@ var creator$r = {
10921
10925
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-gcp/README.md"
10922
10926
  }
10923
10927
  },
10924
- create(context, options) {
10925
- const t = context.createTranslator(messages$q);
10928
+ create(context2, options) {
10929
+ const t = context2.createTranslator(messages$q);
10926
10930
  ({
10927
10931
  allows: options.allows || []
10928
10932
  });
10929
10933
  return {
10930
10934
  file(source) {
10931
10935
  if (source.ext === ".p12") {
10932
- return reportIfFoundPrivateKeyP12Format({ source, context, t });
10936
+ return reportIfFoundPrivateKeyP12Format({ source, context: context2, t });
10933
10937
  } else if (source.ext === ".json") {
10934
- return reportIfFoundPrivateKeyJSONFormat({ source, context, t });
10938
+ return reportIfFoundPrivateKeyJSONFormat({ source, context: context2, t });
10935
10939
  }
10936
10940
  }
10937
10941
  };
@@ -10951,7 +10955,7 @@ var messages$p = {
10951
10955
  ja: (props) => `npm access token: ${props.TOKEN} \u304C\u307F\u3064\u304B\u308A\u307E\u3057\u305F`
10952
10956
  }
10953
10957
  };
10954
- function reportIfFoundXOauthGitHubToken({ source, options, context, t }) {
10958
+ function reportIfFoundXOauthGitHubToken({ source, options, context: context2, t }) {
10955
10959
  const XOAuthPattern = /https?:\/\/(.{1,256}):x-oauth-basic@github.com\//g;
10956
10960
  const results = source.content.matchAll(XOAuthPattern);
10957
10961
  for (const result of results) {
@@ -10962,7 +10966,7 @@ function reportIfFoundXOauthGitHubToken({ source, options, context, t }) {
10962
10966
  if (allowedResults.length > 0) {
10963
10967
  continue;
10964
10968
  }
10965
- context.report({
10969
+ context2.report({
10966
10970
  message: t("PackageJSON_xOauthToken", {
10967
10971
  TOKEN: match
10968
10972
  }),
@@ -10970,7 +10974,7 @@ function reportIfFoundXOauthGitHubToken({ source, options, context, t }) {
10970
10974
  });
10971
10975
  }
10972
10976
  }
10973
- function reportIfFound_AuthTokenInNpmrc({ source, options, context, t }) {
10977
+ function reportIfFound_AuthTokenInNpmrc({ source, options, context: context2, t }) {
10974
10978
  const AuthTokenPattern = /_authToken=([^$].*)/g;
10975
10979
  const results = source.content.matchAll(AuthTokenPattern);
10976
10980
  for (const result of results) {
@@ -10981,7 +10985,7 @@ function reportIfFound_AuthTokenInNpmrc({ source, options, context, t }) {
10981
10985
  if (allowedResults.length > 0) {
10982
10986
  continue;
10983
10987
  }
10984
- context.report({
10988
+ context2.report({
10985
10989
  message: t("Npmrc_authToken", {
10986
10990
  TOKEN: match
10987
10991
  }),
@@ -10989,7 +10993,7 @@ function reportIfFound_AuthTokenInNpmrc({ source, options, context, t }) {
10989
10993
  });
10990
10994
  }
10991
10995
  }
10992
- function reportIfFound_NPM_ACCESS_TOKEN({ source, options, context, t }) {
10996
+ function reportIfFound_NPM_ACCESS_TOKEN({ source, options, context: context2, t }) {
10993
10997
  const NPM_ACCESS_TOKEN_PATTERN = new RegExp("(?<!\\p{L})npm_[A-Za-z0-9_]{36}(?![A-Za-z0-9_])", "gu");
10994
10998
  const results = source.content.matchAll(NPM_ACCESS_TOKEN_PATTERN);
10995
10999
  for (const result of results) {
@@ -11000,7 +11004,7 @@ function reportIfFound_NPM_ACCESS_TOKEN({ source, options, context, t }) {
11000
11004
  if (allowedResults.length > 0) {
11001
11005
  continue;
11002
11006
  }
11003
- context.report({
11007
+ context2.report({
11004
11008
  message: t("NPM_ACCESS_TOKEN", {
11005
11009
  TOKEN: match
11006
11010
  }),
@@ -11031,19 +11035,19 @@ var creator$q = {
11031
11035
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-npm/README.md"
11032
11036
  }
11033
11037
  },
11034
- create(context, options) {
11035
- const t = context.createTranslator(messages$p);
11038
+ create(context2, options) {
11039
+ const t = context2.createTranslator(messages$p);
11036
11040
  const normalizedOptions = {
11037
11041
  allows: options.allows || []
11038
11042
  };
11039
11043
  return {
11040
11044
  file(source) {
11041
11045
  if (isPackageFile(source.filePath)) {
11042
- reportIfFoundXOauthGitHubToken({ source, options: normalizedOptions, context, t });
11046
+ reportIfFoundXOauthGitHubToken({ source, options: normalizedOptions, context: context2, t });
11043
11047
  } else if (isNpmrc(source.filePath)) {
11044
- reportIfFound_AuthTokenInNpmrc({ source, options: normalizedOptions, context, t });
11048
+ reportIfFound_AuthTokenInNpmrc({ source, options: normalizedOptions, context: context2, t });
11045
11049
  }
11046
- reportIfFound_NPM_ACCESS_TOKEN({ source, options: normalizedOptions, context, t });
11050
+ reportIfFound_NPM_ACCESS_TOKEN({ source, options: normalizedOptions, context: context2, t });
11047
11051
  }
11048
11052
  };
11049
11053
  }
@@ -11058,7 +11062,7 @@ var messages$o = {
11058
11062
  ja: (props) => `Slack\u306EIncoming Webhooks: ${props.TOKEN} \u304C\u307F\u3064\u304B\u308A\u307E\u3057\u305F`
11059
11063
  }
11060
11064
  };
11061
- function reportIfFoundRawPrivateKey$1({ source, options, context, t }) {
11065
+ function reportIfFoundRawPrivateKey$1({ source, options, context: context2, t }) {
11062
11066
  const SLACK_TOKEN_PATTERN = /\b(?:xoxb|xoxp|xapp|xoxa|xoxo|xoxr)-(?:\d-)?(?:[a-zA-Z0-9]{1,40}-)+[a-zA-Z0-9]{1,40}\b/g;
11063
11067
  const results = source.content.matchAll(SLACK_TOKEN_PATTERN);
11064
11068
  for (const result of results) {
@@ -11069,7 +11073,7 @@ function reportIfFoundRawPrivateKey$1({ source, options, context, t }) {
11069
11073
  if (allowedResults.length > 0) {
11070
11074
  continue;
11071
11075
  }
11072
- context.report({
11076
+ context2.report({
11073
11077
  message: t("SLACK_TOKEN", {
11074
11078
  TOKEN: match
11075
11079
  }),
@@ -11077,7 +11081,7 @@ function reportIfFoundRawPrivateKey$1({ source, options, context, t }) {
11077
11081
  });
11078
11082
  }
11079
11083
  }
11080
- function reportIfFoundIncomingWebhook({ source, options, context, t }) {
11084
+ function reportIfFoundIncomingWebhook({ source, options, context: context2, t }) {
11081
11085
  const IncomingWebhooksPattern = /https:\/\/hooks\.slack\.com\/services\/T[a-zA-Z0-9]{1,40}\/B[a-zA-Z0-9]{1,40}\/[a-zA-Z0-9]{1,40}/gi;
11082
11086
  const results = source.content.matchAll(IncomingWebhooksPattern);
11083
11087
  for (const result of results) {
@@ -11088,7 +11092,7 @@ function reportIfFoundIncomingWebhook({ source, options, context, t }) {
11088
11092
  if (allowedResults.length > 0) {
11089
11093
  continue;
11090
11094
  }
11091
- context.report({
11095
+ context2.report({
11092
11096
  message: t("IncomingWebhook", {
11093
11097
  URL: match
11094
11098
  }),
@@ -11107,15 +11111,15 @@ var creator$p = {
11107
11111
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-slack/README.md"
11108
11112
  }
11109
11113
  },
11110
- create(context, options) {
11111
- const t = context.createTranslator(messages$o);
11114
+ create(context2, options) {
11115
+ const t = context2.createTranslator(messages$o);
11112
11116
  const normalizedOptions = {
11113
11117
  allows: options.allows || []
11114
11118
  };
11115
11119
  return {
11116
11120
  file(source) {
11117
- reportIfFoundRawPrivateKey$1({ source, options: normalizedOptions, context, t });
11118
- reportIfFoundIncomingWebhook({ source, options: normalizedOptions, context, t });
11121
+ reportIfFoundRawPrivateKey$1({ source, options: normalizedOptions, context: context2, t });
11122
+ reportIfFoundIncomingWebhook({ source, options: normalizedOptions, context: context2, t });
11119
11123
  }
11120
11124
  };
11121
11125
  }
@@ -11180,7 +11184,7 @@ function isLikelyRealPassword(password) {
11180
11184
  return false;
11181
11185
  return true;
11182
11186
  }
11183
- function reportIfFoundBasicAuth({ source, options, context, t }) {
11187
+ function reportIfFoundBasicAuth({ source, options, context: context2, t }) {
11184
11188
  const URL_PATTERN = /(?<protocol>(?:https?|ftp|ftps)):\/\/(?<user>[-a-zA-Z0-9_]{1,256}):(?<password>[-a-zA-Z0-9_]{1,256})@[-a-zA-Z0-9%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b/g;
11185
11189
  const results = source.content.matchAll(URL_PATTERN);
11186
11190
  for (const result of results) {
@@ -11199,7 +11203,7 @@ function reportIfFoundBasicAuth({ source, options, context, t }) {
11199
11203
  if (allowedResults.length > 0) {
11200
11204
  continue;
11201
11205
  }
11202
- context.report({
11206
+ context2.report({
11203
11207
  message: t("BasicAuth", {
11204
11208
  CREDENTIAL: match
11205
11209
  }),
@@ -11218,14 +11222,14 @@ var creator$o = {
11218
11222
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-basicauth/README.md"
11219
11223
  }
11220
11224
  },
11221
- create(context, options) {
11222
- const t = context.createTranslator(messages$n);
11225
+ create(context2, options) {
11226
+ const t = context2.createTranslator(messages$n);
11223
11227
  const normalizedOptions = {
11224
11228
  allows: options.allows || []
11225
11229
  };
11226
11230
  return {
11227
11231
  file(source) {
11228
- reportIfFoundBasicAuth({ source, options: normalizedOptions, context, t });
11232
+ reportIfFoundBasicAuth({ source, options: normalizedOptions, context: context2, t });
11229
11233
  }
11230
11234
  };
11231
11235
  }
@@ -11247,8 +11251,8 @@ var creator$n = {
11247
11251
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-openai/README.md"
11248
11252
  }
11249
11253
  },
11250
- create(context) {
11251
- const t = context.createTranslator(messages$m);
11254
+ create(context2) {
11255
+ const t = context2.createTranslator(messages$m);
11252
11256
  return {
11253
11257
  file(source) {
11254
11258
  const pattern = /sk-(?:proj|svcacct|admin)-(?:[A-Za-z0-9_-]{74}|[A-Za-z0-9_-]{58})T3BlbkFJ(?:[A-Za-z0-9_-]{74}|[A-Za-z0-9_-]{58})\b|sk-[a-zA-Z0-9]{20}T3BlbkFJ[a-zA-Z0-9]{20}/g;
@@ -11257,7 +11261,7 @@ var creator$n = {
11257
11261
  const index = match.index ?? 0;
11258
11262
  const matchString = match[0] ?? "";
11259
11263
  const range = [index, index + matchString.length];
11260
- context.report({
11264
+ context2.report({
11261
11265
  message: t("OPENAI_TOKEN", {
11262
11266
  TOKEN: matchString
11263
11267
  }),
@@ -11285,8 +11289,8 @@ var creator$m = {
11285
11289
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-anthropic/README.md"
11286
11290
  }
11287
11291
  },
11288
- create(context) {
11289
- const t = context.createTranslator(messages$l);
11292
+ create(context2) {
11293
+ const t = context2.createTranslator(messages$l);
11290
11294
  return {
11291
11295
  file(source) {
11292
11296
  const pattern = new RegExp("(?<!\\p{L})sk-ant-api0\\d-[A-Za-z0-9_-]{90,128}AA(?![A-Za-z0-9_-])", "gu");
@@ -11295,7 +11299,7 @@ var creator$m = {
11295
11299
  const index = match.index ?? 0;
11296
11300
  const matchString = match[0] ?? "";
11297
11301
  const range = [index, index + matchString.length];
11298
- context.report({
11302
+ context2.report({
11299
11303
  message: t("ANTHROPIC_API_KEY", {
11300
11304
  KEY: matchString
11301
11305
  }),
@@ -11323,8 +11327,8 @@ var creator$l = {
11323
11327
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-groq/README.md"
11324
11328
  }
11325
11329
  },
11326
- create(context, options) {
11327
- const t = context.createTranslator(messages$k);
11330
+ create(context2, options) {
11331
+ const t = context2.createTranslator(messages$k);
11328
11332
  const normalizedOptions = {
11329
11333
  allows: options?.allows ?? []
11330
11334
  };
@@ -11340,7 +11344,7 @@ var creator$l = {
11340
11344
  continue;
11341
11345
  }
11342
11346
  const range = [index, index + matchString.length];
11343
- context.report({
11347
+ context2.report({
11344
11348
  message: t("GROQ_API_KEY", {
11345
11349
  KEY: matchString
11346
11350
  }),
@@ -11368,8 +11372,8 @@ var creator$k = {
11368
11372
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-huggingface/README.md"
11369
11373
  }
11370
11374
  },
11371
- create(context, options) {
11372
- const t = context.createTranslator(messages$j);
11375
+ create(context2, options) {
11376
+ const t = context2.createTranslator(messages$j);
11373
11377
  const normalizedOptions = {
11374
11378
  allows: options?.allows ?? []
11375
11379
  };
@@ -11385,7 +11389,7 @@ var creator$k = {
11385
11389
  continue;
11386
11390
  }
11387
11391
  const range = [index, index + matchString.length];
11388
- context.report({
11392
+ context2.report({
11389
11393
  message: t("HUGGINGFACE_USER_ACCESS_TOKEN", {
11390
11394
  TOKEN: matchString
11391
11395
  }),
@@ -11413,8 +11417,8 @@ var creator$j = {
11413
11417
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-linear/README.md"
11414
11418
  }
11415
11419
  },
11416
- create(context) {
11417
- const t = context.createTranslator(messages$i);
11420
+ create(context2) {
11421
+ const t = context2.createTranslator(messages$i);
11418
11422
  return {
11419
11423
  file(source) {
11420
11424
  const pattern = new RegExp("(?<!\\p{L})lin_api_[a-zA-Z0-9_]{32,128}(?![a-zA-Z0-9_])", "gu");
@@ -11423,7 +11427,7 @@ var creator$j = {
11423
11427
  const index = match.index ?? 0;
11424
11428
  const matchString = match[0] ?? "";
11425
11429
  const range = [index, index + matchString.length];
11426
- context.report({
11430
+ context2.report({
11427
11431
  message: t("LINEAR_API_TOKEN", {
11428
11432
  ID: matchString
11429
11433
  }),
@@ -11440,7 +11444,7 @@ var messages$h = {
11440
11444
  ja: (props) => `Notion integration \u30C8\u30FC\u30AF\u30F3: ${props.TOKEN} \u304C\u307F\u3064\u304B\u308A\u307E\u3057\u305F`
11441
11445
  }
11442
11446
  };
11443
- function reportIfFoundToken({ source, options, context, t }) {
11447
+ function reportIfFoundToken({ source, options, context: context2, t }) {
11444
11448
  const NOTION_INTEGRATION_TOKEN_PATTERN = new RegExp("(?<!\\p{L})ntn_[0-9]{11}[A-Za-z0-9]{35}(?![A-Za-z0-9])", "gu");
11445
11449
  const results = source.content.matchAll(NOTION_INTEGRATION_TOKEN_PATTERN);
11446
11450
  for (const result of results) {
@@ -11451,7 +11455,7 @@ function reportIfFoundToken({ source, options, context, t }) {
11451
11455
  if (allowedResults.length > 0) {
11452
11456
  continue;
11453
11457
  }
11454
- context.report({
11458
+ context2.report({
11455
11459
  message: t("NOTION_INTEGRATION_TOKEN", {
11456
11460
  TOKEN: match
11457
11461
  }),
@@ -11470,14 +11474,14 @@ var creator$i = {
11470
11474
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-notion/README.md"
11471
11475
  }
11472
11476
  },
11473
- create(context, options) {
11474
- const t = context.createTranslator(messages$h);
11477
+ create(context2, options) {
11478
+ const t = context2.createTranslator(messages$h);
11475
11479
  const normalizedOptions = {
11476
11480
  allows: options.allows ?? []
11477
11481
  };
11478
11482
  return {
11479
11483
  file(source) {
11480
- reportIfFoundToken({ source, options: normalizedOptions, context, t });
11484
+ reportIfFoundToken({ source, options: normalizedOptions, context: context2, t });
11481
11485
  }
11482
11486
  };
11483
11487
  }
@@ -11502,7 +11506,7 @@ function validateBase64KeyContent(base64Content) {
11502
11506
  }
11503
11507
  return true;
11504
11508
  }
11505
- function reportIfFoundRawPrivateKey({ source, options, context, t }) {
11509
+ function reportIfFoundRawPrivateKey({ source, options, context: context2, t }) {
11506
11510
  const results = source.content.matchAll(PEM_CONTENT_PATTERN);
11507
11511
  for (const result of results) {
11508
11512
  const index = result.index || 0;
@@ -11517,7 +11521,7 @@ function reportIfFoundRawPrivateKey({ source, options, context, t }) {
11517
11521
  if (!validateBase64KeyContent(base64Content)) {
11518
11522
  continue;
11519
11523
  }
11520
- context.report({
11524
+ context2.report({
11521
11525
  message: t("PrivateKey", {
11522
11526
  KEY: match
11523
11527
  }),
@@ -11536,14 +11540,14 @@ var creator$h = {
11536
11540
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-privatekey/README.md"
11537
11541
  }
11538
11542
  },
11539
- create(context, options) {
11540
- const t = context.createTranslator(messages$g);
11543
+ create(context2, options) {
11544
+ const t = context2.createTranslator(messages$g);
11541
11545
  const normalizedOptions = {
11542
11546
  allows: options.allows || []
11543
11547
  };
11544
11548
  return {
11545
11549
  file(source) {
11546
- reportIfFoundRawPrivateKey({ source, options: normalizedOptions, context, t });
11550
+ reportIfFoundRawPrivateKey({ source, options: normalizedOptions, context: context2, t });
11547
11551
  }
11548
11552
  };
11549
11553
  }
@@ -11554,7 +11558,7 @@ var messages$f = {
11554
11558
  ja: (props) => `Sendgrid API\u30AD\u30FC\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F\uFF1A ${props.KEY}`
11555
11559
  }
11556
11560
  };
11557
- function reportIfFoundKey$3({ source, options, context, t }) {
11561
+ function reportIfFoundKey$3({ source, options, context: context2, t }) {
11558
11562
  const SENDGRID_KEY_PATTERN = new RegExp("(?<!\\p{L})SG\\.\\w{1,128}\\.\\w{1,128}([-_]?)\\w{1,128}(?!\\w)", "gu");
11559
11563
  const results = source.content.matchAll(SENDGRID_KEY_PATTERN);
11560
11564
  for (const result of results) {
@@ -11568,7 +11572,7 @@ function reportIfFoundKey$3({ source, options, context, t }) {
11568
11572
  if (allowedResults.length > 0) {
11569
11573
  continue;
11570
11574
  }
11571
- context.report({
11575
+ context2.report({
11572
11576
  message: t("SENDGRID_KEY", {
11573
11577
  KEY: match
11574
11578
  }),
@@ -11587,14 +11591,14 @@ var creator$g = {
11587
11591
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-sendgrid/README.md"
11588
11592
  }
11589
11593
  },
11590
- create(context, options) {
11591
- const t = context.createTranslator(messages$f);
11594
+ create(context2, options) {
11595
+ const t = context2.createTranslator(messages$f);
11592
11596
  const normalizedOptions = {
11593
11597
  allows: options.allows || []
11594
11598
  };
11595
11599
  return {
11596
11600
  file(source) {
11597
- reportIfFoundKey$3({ source, options: normalizedOptions, context, t });
11601
+ reportIfFoundKey$3({ source, options: normalizedOptions, context: context2, t });
11598
11602
  }
11599
11603
  };
11600
11604
  }
@@ -11605,7 +11609,7 @@ var messages$e = {
11605
11609
  ja: (props) => `Shopify API\u30AD\u30FC\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F\uFF1A ${props.KEY}`
11606
11610
  }
11607
11611
  };
11608
- function reportIfFoundKey$2({ source, options, context, t }) {
11612
+ function reportIfFoundKey$2({ source, options, context: context2, t }) {
11609
11613
  const SHOPIFY_KEY_PATTERN = new RegExp("(?<!\\p{L})(shppa|shpca|shpat|shpss)_[a-zA-Z0-9]{32,64}(?![a-zA-Z0-9])", "gu");
11610
11614
  const results = source.content.matchAll(SHOPIFY_KEY_PATTERN);
11611
11615
  for (const result of results) {
@@ -11616,7 +11620,7 @@ function reportIfFoundKey$2({ source, options, context, t }) {
11616
11620
  if (allowedResults.length > 0) {
11617
11621
  continue;
11618
11622
  }
11619
- context.report({
11623
+ context2.report({
11620
11624
  message: t("SHOPIFY_KEY", {
11621
11625
  KEY: match
11622
11626
  }),
@@ -11635,14 +11639,14 @@ var creator$f = {
11635
11639
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-shopify/README.md"
11636
11640
  }
11637
11641
  },
11638
- create(context, options) {
11639
- const t = context.createTranslator(messages$e);
11642
+ create(context2, options) {
11643
+ const t = context2.createTranslator(messages$e);
11640
11644
  const normalizedOptions = {
11641
11645
  allows: options.allows || []
11642
11646
  };
11643
11647
  return {
11644
11648
  file(source) {
11645
- reportIfFoundKey$2({ source, options: normalizedOptions, context, t });
11649
+ reportIfFoundKey$2({ source, options: normalizedOptions, context: context2, t });
11646
11650
  }
11647
11651
  };
11648
11652
  }
@@ -11672,7 +11676,7 @@ var messageIdMap$1 = {
11672
11676
  rk_test: "STRIPE_RESTRICTED_KEY_TEST"
11673
11677
  };
11674
11678
  var STRIPE_KEY_PATTERN = new RegExp("(?<!\\p{L})(?<prefix>sk_live|sk_test|rk_live|rk_test)_[a-zA-Z0-9]{24,99}(?![a-zA-Z0-9])", "gu");
11675
- function reportIfFound$2({ source, options, context, t }) {
11679
+ function reportIfFound$2({ source, options, context: context2, t }) {
11676
11680
  const results = source.content.matchAll(STRIPE_KEY_PATTERN);
11677
11681
  for (const result of results) {
11678
11682
  const index = result.index ?? 0;
@@ -11686,7 +11690,7 @@ function reportIfFound$2({ source, options, context, t }) {
11686
11690
  if (allowedResults.length > 0) {
11687
11691
  continue;
11688
11692
  }
11689
- context.report({
11693
+ context2.report({
11690
11694
  message: t(messageIdMap$1[prefix], {
11691
11695
  KEY: match
11692
11696
  }),
@@ -11705,14 +11709,14 @@ var creator$e = {
11705
11709
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-stripe/README.md"
11706
11710
  }
11707
11711
  },
11708
- create(context, options) {
11709
- const t = context.createTranslator(messages$d);
11712
+ create(context2, options) {
11713
+ const t = context2.createTranslator(messages$d);
11710
11714
  const normalizedOptions = {
11711
11715
  allows: options.allows ?? []
11712
11716
  };
11713
11717
  return {
11714
11718
  file(source) {
11715
- reportIfFound$2({ source, options: normalizedOptions, context, t });
11719
+ reportIfFound$2({ source, options: normalizedOptions, context: context2, t });
11716
11720
  }
11717
11721
  };
11718
11722
  }
@@ -11731,7 +11735,7 @@ var typeMap = /* @__PURE__ */ new Map([
11731
11735
  ["ghr", "refresh tokens"],
11732
11736
  ["github_pat", "fine-grained personal access tokens"]
11733
11737
  ]);
11734
- function reportIfFoundKey$1({ pattern, source, options, context, t }) {
11738
+ function reportIfFoundKey$1({ pattern, source, options, context: context2, t }) {
11735
11739
  const results = source.content.matchAll(pattern);
11736
11740
  for (const result of results) {
11737
11741
  const index = result.index || 0;
@@ -11746,7 +11750,7 @@ function reportIfFoundKey$1({ pattern, source, options, context, t }) {
11746
11750
  if (allowedResults.length > 0) {
11747
11751
  continue;
11748
11752
  }
11749
- context.report({
11753
+ context2.report({
11750
11754
  message: t("GITHUB_TOKEN", {
11751
11755
  KEY: match,
11752
11756
  typeName
@@ -11766,7 +11770,7 @@ var creator$d = {
11766
11770
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-github/README.md"
11767
11771
  }
11768
11772
  },
11769
- create(context, options) {
11773
+ create(context2, options) {
11770
11774
  const CLASSIC_GITHUB_TOKEN_PATTERN = new RegExp("(?<!\\p{L})(?<type>ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{36}(?![A-Za-z0-9_])", "gu");
11771
11775
  const FINE_GRAINED_GITHUB_TOKEN_PATTERN = new RegExp("(?<!\\p{L})(?<type>github_pat)_[A-Za-z0-9_]{82}(?![A-Za-z0-9_])", "gu");
11772
11776
  const GITHUB_APP_INSTALLATION_TOKEN_PATTERN = new RegExp("(?<!\\p{L})(?<type>ghs)_[0-9]{1,20}_[A-Za-z0-9_-]{1,1000}\\.[A-Za-z0-9_-]{1,10000}\\.[A-Za-z0-9_-]{1,1000}(?![A-Za-z0-9_-])", "gu");
@@ -11775,14 +11779,14 @@ var creator$d = {
11775
11779
  FINE_GRAINED_GITHUB_TOKEN_PATTERN,
11776
11780
  GITHUB_APP_INSTALLATION_TOKEN_PATTERN
11777
11781
  ];
11778
- const t = context.createTranslator(messages$c);
11782
+ const t = context2.createTranslator(messages$c);
11779
11783
  const normalizedOptions = {
11780
11784
  allows: options.allows || []
11781
11785
  };
11782
11786
  return {
11783
11787
  file(source) {
11784
11788
  for (const pattern of patterns) {
11785
- reportIfFoundKey$1({ pattern, source, options: normalizedOptions, context, t });
11789
+ reportIfFoundKey$1({ pattern, source, options: normalizedOptions, context: context2, t });
11786
11790
  }
11787
11791
  }
11788
11792
  };
@@ -11794,7 +11798,7 @@ var messages$b = {
11794
11798
  ja: (props) => `GitLab Personal Access Token\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F: ${props.KEY}`
11795
11799
  }
11796
11800
  };
11797
- function reportIfFoundKey({ pattern, source, options, context, t }) {
11801
+ function reportIfFoundKey({ pattern, source, options, context: context2, t }) {
11798
11802
  const results = source.content.matchAll(pattern);
11799
11803
  for (const result of results) {
11800
11804
  const index = result.index ?? 0;
@@ -11804,7 +11808,7 @@ function reportIfFoundKey({ pattern, source, options, context, t }) {
11804
11808
  if (allowedResults.length > 0) {
11805
11809
  continue;
11806
11810
  }
11807
- context.report({
11811
+ context2.report({
11808
11812
  message: t("GITLAB_PERSONAL_ACCESS_TOKEN", {
11809
11813
  KEY: match
11810
11814
  }),
@@ -11823,17 +11827,17 @@ var creator$c = {
11823
11827
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-gitlab/README.md"
11824
11828
  }
11825
11829
  },
11826
- create(context, options) {
11830
+ create(context2, options) {
11827
11831
  const GITLAB_PERSONAL_ACCESS_TOKEN_PATTERN = new RegExp("(?<!\\p{L})glpat-[A-Za-z0-9_-]{20,128}(?![A-Za-z0-9_-])", "gu");
11828
11832
  const patterns = [GITLAB_PERSONAL_ACCESS_TOKEN_PATTERN];
11829
- const t = context.createTranslator(messages$b);
11833
+ const t = context2.createTranslator(messages$b);
11830
11834
  const normalizedOptions = {
11831
11835
  allows: options.allows ?? []
11832
11836
  };
11833
11837
  return {
11834
11838
  file(source) {
11835
11839
  for (const pattern of patterns) {
11836
- reportIfFoundKey({ pattern, source, options: normalizedOptions, context, t });
11840
+ reportIfFoundKey({ pattern, source, options: normalizedOptions, context: context2, t });
11837
11841
  }
11838
11842
  }
11839
11843
  };
@@ -11849,7 +11853,7 @@ var messages$a = {
11849
11853
  ja: (props) => `Grafana Service Account \u30C8\u30FC\u30AF\u30F3: ${props.TOKEN} \u304C\u307F\u3064\u304B\u308A\u307E\u3057\u305F`
11850
11854
  }
11851
11855
  };
11852
- function reportIfFound$1({ pattern, messageId, source, options, context, t }) {
11856
+ function reportIfFound$1({ pattern, messageId, source, options, context: context2, t }) {
11853
11857
  const results = source.content.matchAll(pattern);
11854
11858
  for (const result of results) {
11855
11859
  const index = result.index ?? 0;
@@ -11859,7 +11863,7 @@ function reportIfFound$1({ pattern, messageId, source, options, context, t }) {
11859
11863
  continue;
11860
11864
  }
11861
11865
  const range = [index, index + match.length];
11862
- context.report({
11866
+ context2.report({
11863
11867
  message: t(messageId, {
11864
11868
  TOKEN: match
11865
11869
  }),
@@ -11878,8 +11882,8 @@ var creator$b = {
11878
11882
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-grafana/README.md"
11879
11883
  }
11880
11884
  },
11881
- create(context, options) {
11882
- const t = context.createTranslator(messages$a);
11885
+ create(context2, options) {
11886
+ const t = context2.createTranslator(messages$a);
11883
11887
  const normalizedOptions = {
11884
11888
  allows: options?.allows ?? []
11885
11889
  };
@@ -11892,7 +11896,7 @@ var creator$b = {
11892
11896
  messageId: "GRAFANA_CLOUD_API_TOKEN",
11893
11897
  source,
11894
11898
  options: normalizedOptions,
11895
- context,
11899
+ context: context2,
11896
11900
  t
11897
11901
  });
11898
11902
  reportIfFound$1({
@@ -11900,7 +11904,7 @@ var creator$b = {
11900
11904
  messageId: "GRAFANA_SERVICE_ACCOUNT_TOKEN",
11901
11905
  source,
11902
11906
  options: normalizedOptions,
11903
- context,
11907
+ context: context2,
11904
11908
  t
11905
11909
  });
11906
11910
  }
@@ -11933,8 +11937,8 @@ var creator$a = {
11933
11937
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-1password/README.md"
11934
11938
  }
11935
11939
  },
11936
- create(context, options) {
11937
- const t = context.createTranslator(messages$9);
11940
+ create(context2, options) {
11941
+ const t = context2.createTranslator(messages$9);
11938
11942
  const normalizedOptions = {
11939
11943
  allows: options?.allows ?? []
11940
11944
  };
@@ -11954,7 +11958,7 @@ var creator$a = {
11954
11958
  continue;
11955
11959
  }
11956
11960
  const range = [index, index + matchString.length];
11957
- context.report({
11961
+ context2.report({
11958
11962
  message: t("OPS_TOKEN", {
11959
11963
  TOKEN: matchString
11960
11964
  }),
@@ -12036,7 +12040,7 @@ function isLikelyRealCredential(username, password) {
12036
12040
  return false;
12037
12041
  return true;
12038
12042
  }
12039
- function reportMongoDBConnectionString({ source, options, context, t }) {
12043
+ function reportMongoDBConnectionString({ source, options, context: context2, t }) {
12040
12044
  const MONGODB_PATTERN = /mongodb(?:\+srv)?:\/\/(?:(?<username>[^:\/\s]{1,100}):(?<password>[^@\/\s]{1,200})@)?(?<host>[^\/\s?]{1,100})(?:\/(?<database>[^?\s]{0,100}))?(?:\?(?<options>[^\s]{0,500}))?/gi;
12041
12045
  const results = source.content.matchAll(MONGODB_PATTERN);
12042
12046
  for (const result of results) {
@@ -12053,7 +12057,7 @@ function reportMongoDBConnectionString({ source, options, context, t }) {
12053
12057
  if (allowedResults.length > 0) {
12054
12058
  continue;
12055
12059
  }
12056
- context.report({
12060
+ context2.report({
12057
12061
  message: t("MongoDBConnection", {
12058
12062
  URI: match
12059
12063
  }),
@@ -12061,7 +12065,7 @@ function reportMongoDBConnectionString({ source, options, context, t }) {
12061
12065
  });
12062
12066
  }
12063
12067
  }
12064
- function reportMySQLConnectionString({ source, options, context, t }) {
12068
+ function reportMySQLConnectionString({ source, options, context: context2, t }) {
12065
12069
  const MYSQL_URI_PATTERN = /(?:jdbc:)?mysql(?:x)?:\/\/(?:(?<username>[^:\/\s]{1,100}):(?<password>[^@\/\s]{1,200})@)?(?<host>[^\/\s?]{1,100})(?:\/(?<database>[^?\s]{0,100}))?(?:\?(?<options>[^\s]{0,500}))?/gi;
12066
12070
  const results = source.content.matchAll(MYSQL_URI_PATTERN);
12067
12071
  for (const result of results) {
@@ -12078,7 +12082,7 @@ function reportMySQLConnectionString({ source, options, context, t }) {
12078
12082
  if (allowedResults.length > 0) {
12079
12083
  continue;
12080
12084
  }
12081
- context.report({
12085
+ context2.report({
12082
12086
  message: t("MySQLConnection", {
12083
12087
  URI: match
12084
12088
  }),
@@ -12086,7 +12090,7 @@ function reportMySQLConnectionString({ source, options, context, t }) {
12086
12090
  });
12087
12091
  }
12088
12092
  }
12089
- function reportPostgreSQLConnectionString({ source, options, context, t }) {
12093
+ function reportPostgreSQLConnectionString({ source, options, context: context2, t }) {
12090
12094
  const POSTGRESQL_URI_PATTERN = /postgres(?:ql)?:\/\/(?:(?<username>[^:\/\s]{1,100}):(?<password>[^@\/\s]{1,200})@)?(?<host>[^\/\s?]{1,100})(?:\/(?<database>[^?\s]{0,100}))?(?:\?(?<options>[^\s]{0,500}))?/gi;
12091
12095
  const results = source.content.matchAll(POSTGRESQL_URI_PATTERN);
12092
12096
  for (const result of results) {
@@ -12103,7 +12107,7 @@ function reportPostgreSQLConnectionString({ source, options, context, t }) {
12103
12107
  if (allowedResults.length > 0) {
12104
12108
  continue;
12105
12109
  }
12106
- context.report({
12110
+ context2.report({
12107
12111
  message: t("PostgreSQLConnection", {
12108
12112
  URI: match
12109
12113
  }),
@@ -12122,16 +12126,16 @@ var creator$9 = {
12122
12126
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-database-connection-string/README.md"
12123
12127
  }
12124
12128
  },
12125
- create(context, options) {
12129
+ create(context2, options) {
12126
12130
  const normalizedOptions = {
12127
12131
  allows: options.allows || []
12128
12132
  };
12129
- const t = context.createTranslator(messages$8);
12133
+ const t = context2.createTranslator(messages$8);
12130
12134
  return {
12131
12135
  file(source) {
12132
- reportMongoDBConnectionString({ source, options: normalizedOptions, context, t });
12133
- reportMySQLConnectionString({ source, options: normalizedOptions, context, t });
12134
- reportPostgreSQLConnectionString({ source, options: normalizedOptions, context, t });
12136
+ reportMongoDBConnectionString({ source, options: normalizedOptions, context: context2, t });
12137
+ reportMySQLConnectionString({ source, options: normalizedOptions, context: context2, t });
12138
+ reportPostgreSQLConnectionString({ source, options: normalizedOptions, context: context2, t });
12135
12139
  }
12136
12140
  };
12137
12141
  }
@@ -12164,8 +12168,8 @@ var creator$8 = {
12164
12168
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-hashicorp-vault/README.md"
12165
12169
  }
12166
12170
  },
12167
- create(context, options) {
12168
- const t = context.createTranslator(messages$7);
12171
+ create(context2, options) {
12172
+ const t = context2.createTranslator(messages$7);
12169
12173
  const normalizedOptions = {
12170
12174
  allows: options?.allows ?? []
12171
12175
  };
@@ -12179,7 +12183,7 @@ var creator$8 = {
12179
12183
  continue;
12180
12184
  }
12181
12185
  const range = [index, index + matchString.length];
12182
- context.report({
12186
+ context2.report({
12183
12187
  message: t(messageId, {
12184
12188
  TOKEN: matchString
12185
12189
  }),
@@ -12236,8 +12240,8 @@ var creator$7 = {
12236
12240
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-vercel/README.md"
12237
12241
  }
12238
12242
  },
12239
- create(context, options) {
12240
- const t = context.createTranslator(messages$6);
12243
+ create(context2, options) {
12244
+ const t = context2.createTranslator(messages$6);
12241
12245
  const normalizedOptions = {
12242
12246
  allows: options?.allows ?? []
12243
12247
  };
@@ -12255,7 +12259,7 @@ var creator$7 = {
12255
12259
  continue;
12256
12260
  }
12257
12261
  const range = [index, index + matchString.length];
12258
- context.report({
12262
+ context2.report({
12259
12263
  message: t(messageId, {
12260
12264
  ID: matchString
12261
12265
  }),
@@ -12283,8 +12287,8 @@ var creator$6 = {
12283
12287
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-databricks/README.md"
12284
12288
  }
12285
12289
  },
12286
- create(context, options) {
12287
- const t = context.createTranslator(messages$5);
12290
+ create(context2, options) {
12291
+ const t = context2.createTranslator(messages$5);
12288
12292
  const normalizedOptions = {
12289
12293
  allows: options?.allows ?? []
12290
12294
  };
@@ -12300,7 +12304,7 @@ var creator$6 = {
12300
12304
  continue;
12301
12305
  }
12302
12306
  const range = [index, index + matchString.length];
12303
- context.report({
12307
+ context2.report({
12304
12308
  message: t("DATABRICKS_PERSONAL_ACCESS_TOKEN", {
12305
12309
  ID: matchString
12306
12310
  }),
@@ -12317,7 +12321,7 @@ var messages$4 = {
12317
12321
  ja: (props) => `Docker Personal Access Token: ${props.TOKEN} \u304C\u307F\u3064\u304B\u308A\u307E\u3057\u305F`
12318
12322
  }
12319
12323
  };
12320
- function reportIfFoundDockerPAT({ source, options, context, t }) {
12324
+ function reportIfFoundDockerPAT({ source, options, context: context2, t }) {
12321
12325
  const DOCKER_PAT_PATTERN = new RegExp("(?<!\\p{L})dckr_pat_[a-zA-Z0-9_-]{27}(?![a-zA-Z0-9_-])", "gu");
12322
12326
  const results = source.content.matchAll(DOCKER_PAT_PATTERN);
12323
12327
  for (const result of results) {
@@ -12328,7 +12332,7 @@ function reportIfFoundDockerPAT({ source, options, context, t }) {
12328
12332
  if (allowedResults.length > 0) {
12329
12333
  continue;
12330
12334
  }
12331
- context.report({
12335
+ context2.report({
12332
12336
  message: t("DOCKER_PERSONAL_ACCESS_TOKEN", {
12333
12337
  TOKEN: match
12334
12338
  }),
@@ -12347,14 +12351,14 @@ var creator$5 = {
12347
12351
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-docker/README.md"
12348
12352
  }
12349
12353
  },
12350
- create(context, options) {
12351
- const t = context.createTranslator(messages$4);
12354
+ create(context2, options) {
12355
+ const t = context2.createTranslator(messages$4);
12352
12356
  const normalizedOptions = {
12353
12357
  allows: options.allows || []
12354
12358
  };
12355
12359
  return {
12356
12360
  file(source) {
12357
- reportIfFoundDockerPAT({ source, options: normalizedOptions, context, t });
12361
+ reportIfFoundDockerPAT({ source, options: normalizedOptions, context: context2, t });
12358
12362
  }
12359
12363
  };
12360
12364
  }
@@ -12376,8 +12380,8 @@ var creator$4 = {
12376
12380
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-figma/README.md"
12377
12381
  }
12378
12382
  },
12379
- create(context, options) {
12380
- const t = context.createTranslator(messages$3);
12383
+ create(context2, options) {
12384
+ const t = context2.createTranslator(messages$3);
12381
12385
  const normalizedOptions = {
12382
12386
  allows: options?.allows ?? []
12383
12387
  };
@@ -12393,7 +12397,7 @@ var creator$4 = {
12393
12397
  continue;
12394
12398
  }
12395
12399
  const range = [index, index + matchString.length];
12396
- context.report({
12400
+ context2.report({
12397
12401
  message: t("FIGMA_PERSONAL_ACCESS_TOKEN", {
12398
12402
  ID: matchString
12399
12403
  }),
@@ -12424,7 +12428,7 @@ var messageIdMap = {
12424
12428
  cfat: "CLOUDFLARE_ACCOUNT_API_TOKEN"
12425
12429
  };
12426
12430
  var CLOUDFLARE_TOKEN_PATTERN = new RegExp("(?<!\\p{L})(?<prefix>cfk|cfut|cfat)_[A-Za-z0-9]{40}[0-9a-f]{8}(?![A-Za-z0-9])", "gu");
12427
- function reportIfFound({ source, options, context, t }) {
12431
+ function reportIfFound({ source, options, context: context2, t }) {
12428
12432
  const results = source.content.matchAll(CLOUDFLARE_TOKEN_PATTERN);
12429
12433
  for (const result of results) {
12430
12434
  const index = result.index ?? 0;
@@ -12438,7 +12442,7 @@ function reportIfFound({ source, options, context, t }) {
12438
12442
  if (allowedResults.length > 0) {
12439
12443
  continue;
12440
12444
  }
12441
- context.report({
12445
+ context2.report({
12442
12446
  message: t(messageIdMap[prefix], {
12443
12447
  TOKEN: match
12444
12448
  }),
@@ -12457,14 +12461,14 @@ var creator$3 = {
12457
12461
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-cloudflare/README.md"
12458
12462
  }
12459
12463
  },
12460
- create(context, options) {
12461
- const t = context.createTranslator(messages$2);
12464
+ create(context2, options) {
12465
+ const t = context2.createTranslator(messages$2);
12462
12466
  const normalizedOptions = {
12463
12467
  allows: options.allows ?? []
12464
12468
  };
12465
12469
  return {
12466
12470
  file(source) {
12467
- reportIfFound({ source, options: normalizedOptions, context, t });
12471
+ reportIfFound({ source, options: normalizedOptions, context: context2, t });
12468
12472
  }
12469
12473
  };
12470
12474
  }
@@ -12513,8 +12517,8 @@ var creator$2 = {
12513
12517
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-tailscale/README.md"
12514
12518
  }
12515
12519
  },
12516
- create(context, options) {
12517
- const t = context.createTranslator(messages$1);
12520
+ create(context2, options) {
12521
+ const t = context2.createTranslator(messages$1);
12518
12522
  const normalizedOptions = {
12519
12523
  allows: options.allows ?? []
12520
12524
  };
@@ -12532,7 +12536,7 @@ var creator$2 = {
12532
12536
  continue;
12533
12537
  }
12534
12538
  const messageId = messageIdByType[type] ?? "TAILSCALE_KEY";
12535
- context.report({
12539
+ context2.report({
12536
12540
  message: t(messageId, {
12537
12541
  KEY: matchString
12538
12542
  }),
@@ -12694,8 +12698,8 @@ var creator$1 = {
12694
12698
  url: "https://github.com/secretlint/secretlint/blob/master/packages/%40secretlint/secretlint-rule-filter-comments/README.md"
12695
12699
  }
12696
12700
  },
12697
- create(context) {
12698
- const t = context.createTranslator(messages);
12701
+ create(context2) {
12702
+ const t = context2.createTranslator(messages);
12699
12703
  return {
12700
12704
  file(source) {
12701
12705
  const state = new CommentState(source);
@@ -12712,7 +12716,7 @@ var creator$1 = {
12712
12716
  }
12713
12717
  }
12714
12718
  state.getIgnoringMessages().forEach((message) => {
12715
- context.ignore({
12719
+ context2.ignore({
12716
12720
  message: t("IGNORE_MESSAGE"),
12717
12721
  range: [message.startIndex, message.endIndex],
12718
12722
  targetRuleId: message.ruleId
@@ -15813,7 +15817,7 @@ function putProp2(target, key, value) {
15813
15817
  else
15814
15818
  target[key] = value;
15815
15819
  }
15816
- function mirrorShape2(target, source, keys, wrap) {
15820
+ function mirrorShape2(target, source, keys, wrap2) {
15817
15821
  const raw = sourceShape2(source);
15818
15822
  for (const key of keys) {
15819
15823
  const desc = Object.getOwnPropertyDescriptor(raw, key);
@@ -15822,10 +15826,10 @@ function mirrorShape2(target, source, keys, wrap) {
15822
15826
  if (desc.get) {
15823
15827
  deferProp2(target, key, () => {
15824
15828
  const value = source._zod.def.shape[key];
15825
- return wrap ? wrap(value, key) : value;
15829
+ return wrap2 ? wrap2(value, key) : value;
15826
15830
  });
15827
15831
  } else
15828
- putProp2(target, key, wrap ? wrap(desc.value, key) : desc.value);
15832
+ putProp2(target, key, wrap2 ? wrap2(desc.value, key) : desc.value);
15829
15833
  }
15830
15834
  }
15831
15835
  function mirrorProps2(target, source) {
@@ -16672,9 +16676,9 @@ function formatError2(error3, mapper = (issue3) => issue3.message) {
16672
16676
  let i = 0;
16673
16677
  while (i < fullpath.length) {
16674
16678
  const el = fullpath[i];
16675
- const terminal = i === fullpath.length - 1;
16679
+ const terminal2 = i === fullpath.length - 1;
16676
16680
  if (el === "_errors") {
16677
- if (terminal)
16681
+ if (terminal2)
16678
16682
  curr._errors.push(mapper(issue3));
16679
16683
  i++;
16680
16684
  continue;
@@ -16688,7 +16692,7 @@ function formatError2(error3, mapper = (issue3) => issue3.message) {
16688
16692
  });
16689
16693
  }
16690
16694
  const node3 = curr[el];
16691
- if (terminal) {
16695
+ if (terminal2) {
16692
16696
  node3._errors.push(mapper(issue3));
16693
16697
  }
16694
16698
  curr = node3;
@@ -23946,12 +23950,14 @@ ${detail}` : ""}`,
23946
23950
  }
23947
23951
  async function stopTask(source) {
23948
23952
  const task = await observedTask(source);
23949
- if (task === null || task.state === 1 || task.state === 3) return;
23953
+ if (task === null) return false;
23954
+ if (task.state === 1 || task.state === 3) return true;
23950
23955
  await schtasks(source, "/End");
23951
23956
  const deadline = Date.now() + TASK_TIMEOUT_MS;
23952
23957
  while (Date.now() < deadline) {
23953
23958
  const current = await observedTask(source);
23954
- if (current === null || current.state === 1 || current.state === 3) return;
23959
+ if (current === null) return false;
23960
+ if (current.state === 1 || current.state === 3) return true;
23955
23961
  await delay3(100);
23956
23962
  }
23957
23963
  throw new Error(`Windows did not stop the ${source} collector task.`);
@@ -23987,9 +23993,7 @@ async function installScheduledTask(dataDirectory2, source) {
23987
23993
  return file;
23988
23994
  }
23989
23995
  async function uninstallScheduledTask(source) {
23990
- await stopTask(source);
23991
- if (await observedTask(source) !== null)
23992
- await schtasks(source, "/Delete", "/F");
23996
+ if (await stopTask(source)) await schtasks(source, "/Delete", "/F");
23993
23997
  await fs15.rm(taskDefinitionPath(source), { force: true });
23994
23998
  }
23995
23999
  async function scheduledTaskStatus(source) {
@@ -24242,9 +24246,13 @@ async function uninstallCursorHooks(cursorHome, dataDirectory2) {
24242
24246
  }
24243
24247
 
24244
24248
  // src/logger.ts
24245
- configureCollectorLogging(() => ({
24249
+ var context = () => ({
24246
24250
  runtimeVersion: process.env.ITERATION_RUNTIME_VERSION ?? null
24247
- }));
24251
+ });
24252
+ configureCollectorLogging(context);
24253
+ function silenceCollectorLogs() {
24254
+ configureCollectorLogging(context, () => void 0);
24255
+ }
24248
24256
 
24249
24257
  // src/turn-summary.ts
24250
24258
  import { execFile as execFileCallback7 } from "node:child_process";
@@ -24976,8 +24984,157 @@ async function connectedConfig(source) {
24976
24984
 
24977
24985
  // src/clerk-device-auth.ts
24978
24986
  import { execFile as execFile8 } from "node:child_process";
24979
- import { createInterface } from "node:readline/promises";
24980
24987
  import { promisify as promisify8 } from "node:util";
24988
+
24989
+ // src/terminal.ts
24990
+ import { createInterface } from "node:readline/promises";
24991
+ import { stripVTControlCharacters, styleText } from "node:util";
24992
+ var MEASURE = 80;
24993
+ var INDENT = " ";
24994
+ var UNICODE_SYMBOLS = {
24995
+ brand: "\u25C6",
24996
+ success: "\u2713",
24997
+ warning: "!",
24998
+ failure: "\u2717",
24999
+ question: "?",
25000
+ on: "\u25CF",
25001
+ off: "\u25CB",
25002
+ spinner: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"]
25003
+ };
25004
+ var BASIC_SYMBOLS = {
25005
+ brand: "*",
25006
+ success: "\u221A",
25007
+ warning: "!",
25008
+ failure: "\xD7",
25009
+ question: "?",
25010
+ on: "*",
25011
+ off: "-",
25012
+ spinner: ["-", "\\", "|", "/"]
25013
+ };
25014
+ var TONE_FORMAT = {
25015
+ success: "green",
25016
+ warning: "yellow",
25017
+ failure: "red",
25018
+ muted: "dim"
25019
+ };
25020
+ function supportsUnicode(env) {
25021
+ if (process.platform !== "win32") return env.TERM !== "linux";
25022
+ return env.WT_SESSION !== void 0 || env.TERM_PROGRAM === "vscode" || env.TERMINAL_EMULATOR === "JetBrains-JediTerm" || env.ConEmuTask === "{cmd::Cmder}" || env.TERM === "xterm-256color" || env.TERM === "alacritty";
25023
+ }
25024
+ function terminalFor(stream, env = process.env) {
25025
+ const style = (format) => (text) => styleText(format, text, { stream });
25026
+ return {
25027
+ width: stream.isTTY && stream.columns > 0 ? Math.min(stream.columns, MEASURE) : MEASURE,
25028
+ symbols: supportsUnicode(env) ? UNICODE_SYMBOLS : BASIC_SYMBOLS,
25029
+ bold: style("bold"),
25030
+ dim: style("dim"),
25031
+ link: style("underline"),
25032
+ tone: (tone, text) => style(TONE_FORMAT[tone])(text)
25033
+ };
25034
+ }
25035
+ function safeWorkspaceName(value) {
25036
+ const cleaned = value?.split("").map((character) => {
25037
+ const code = character.charCodeAt(0);
25038
+ return code < 32 || code >= 127 && code <= 159 ? " " : character;
25039
+ }).join("").replace(/\s+/g, " ").trim();
25040
+ return cleaned === void 0 || cleaned === "" ? null : cleaned;
25041
+ }
25042
+ function visibleWidth(text) {
25043
+ return stripVTControlCharacters(text).length;
25044
+ }
25045
+ function padEnd(text, width) {
25046
+ return text + " ".repeat(Math.max(0, width - visibleWidth(text)));
25047
+ }
25048
+ function brand(terminal2, workspaceName = null) {
25049
+ const name = safeWorkspaceName(workspaceName);
25050
+ return `${terminal2.bold(`${terminal2.symbols.brand} Iteration`)}${name === null ? "" : `${terminal2.dim(" \xB7 ")}${name}`}`;
25051
+ }
25052
+ function wrap(terminal2, text, options = {}) {
25053
+ const indent = options.indent ?? INDENT;
25054
+ const style = options.style ?? ((line) => line);
25055
+ const lines = [];
25056
+ let prefix = options.first ?? indent;
25057
+ let words = [];
25058
+ let width = visibleWidth(prefix);
25059
+ const flush = () => {
25060
+ lines.push(`${prefix}${style(words.join(" "))}`.trimEnd());
25061
+ prefix = indent;
25062
+ words = [];
25063
+ width = visibleWidth(indent);
25064
+ };
25065
+ for (const word of text.split(" ")) {
25066
+ const wordWidth = visibleWidth(word);
25067
+ if (words.length > 0 && width + 1 + wordWidth > terminal2.width) flush();
25068
+ if (words.length === 0 && word === "" && lines.length > 0) continue;
25069
+ width += (words.length > 0 ? 1 : 0) + wordWidth;
25070
+ words.push(word);
25071
+ }
25072
+ flush();
25073
+ return lines.join("\n");
25074
+ }
25075
+ function mark(terminal2, kind, text, indent = "") {
25076
+ const tone = kind === "question" ? "success" : kind;
25077
+ return wrap(terminal2, text, {
25078
+ first: `${indent}${terminal2.tone(tone, terminal2.symbols[kind])} `,
25079
+ indent: `${indent}${INDENT}`
25080
+ });
25081
+ }
25082
+ function rows(terminal2, entries2, indent = INDENT) {
25083
+ const labelWidth = Math.max(
25084
+ 0,
25085
+ ...entries2.map(([label2]) => visibleWidth(label2))
25086
+ );
25087
+ const hanging = " ".repeat(visibleWidth(indent) + labelWidth + 2);
25088
+ return entries2.map(
25089
+ ([label2, value]) => wrap(terminal2, value, {
25090
+ first: `${indent}${padEnd(label2, labelWidth + 2)}`,
25091
+ indent: hanging
25092
+ })
25093
+ ).join("\n");
25094
+ }
25095
+ var SPINNER_INTERVAL_MS = 80;
25096
+ function startSpinner(stream, terminal2, text) {
25097
+ if (!stream.isTTY) {
25098
+ stream.write(`${text}
25099
+ `);
25100
+ return () => void 0;
25101
+ }
25102
+ const frames = terminal2.symbols.spinner;
25103
+ let frame = 0;
25104
+ const draw = () => {
25105
+ stream.cursorTo(0);
25106
+ stream.clearLine(1);
25107
+ stream.write(`${terminal2.dim(frames[frame % frames.length])} ${text}`);
25108
+ frame += 1;
25109
+ };
25110
+ draw();
25111
+ const timer = setInterval(draw, SPINNER_INTERVAL_MS);
25112
+ timer.unref();
25113
+ return () => {
25114
+ clearInterval(timer);
25115
+ stream.cursorTo(0);
25116
+ stream.clearLine(0);
25117
+ };
25118
+ }
25119
+ async function ask(terminal2, question) {
25120
+ const prompt = createInterface({
25121
+ input: process.stdin,
25122
+ output: process.stdout
25123
+ });
25124
+ try {
25125
+ return await prompt.question(
25126
+ `${terminal2.tone("success", terminal2.symbols.question)} ${question} `
25127
+ );
25128
+ } catch (error3) {
25129
+ if (!(error3 instanceof Error && error3.name === "AbortError")) throw error3;
25130
+ process.stdout.write("\n");
25131
+ return null;
25132
+ } finally {
25133
+ prompt.close();
25134
+ }
25135
+ }
25136
+
25137
+ // src/clerk-device-auth.ts
24981
25138
  var execFileAsync = promisify8(execFile8);
24982
25139
  var serverAuthConfigSchema = object3({
24983
25140
  issuerUrl: url(),
@@ -25081,7 +25238,11 @@ $start.UseShellExecute = $true
25081
25238
  await execFileAsync("xdg-open", [url2], { timeout: 5e3 });
25082
25239
  else await execFileAsync("open", [url2], { timeout: 5e3 });
25083
25240
  } catch {
25084
- process.stdout.write("Open the verification link in your browser.\n");
25241
+ const terminal2 = terminalFor(process.stdout);
25242
+ process.stdout.write(
25243
+ `${mark(terminal2, "warning", "Your browser did not open. Open the link above to sign in.")}
25244
+ `
25245
+ );
25085
25246
  }
25086
25247
  }
25087
25248
  function delay4(milliseconds) {
@@ -25161,17 +25322,39 @@ async function clerkDeviceSignIn(configuration) {
25161
25322
  configuration.clientId
25162
25323
  );
25163
25324
  const verificationUrl = challenge.verification_uri_complete ?? challenge.verification_uri;
25325
+ const terminal2 = terminalFor(process.stdout);
25164
25326
  process.stdout.write(
25165
- "Sign in to Iteration in your browser and confirm this code.\nCode: " + challenge.user_code + "\nLink: " + verificationUrl + "\n"
25327
+ [
25328
+ "",
25329
+ wrap(
25330
+ terminal2,
25331
+ "Sign in to Iteration in your browser and confirm this code",
25332
+ { style: terminal2.bold }
25333
+ ),
25334
+ rows(terminal2, [
25335
+ ["Code", terminal2.bold(challenge.user_code)],
25336
+ ["Link", terminal2.link(verificationUrl)]
25337
+ ]),
25338
+ ""
25339
+ ].join("\n")
25166
25340
  );
25167
25341
  await openBrowser(verificationUrl);
25168
- return pollForAccessToken(
25169
- endpoints.tokenUrl,
25170
- configuration.clientId,
25171
- challenge.device_code,
25172
- challenge.expires_in,
25173
- challenge.interval
25342
+ const stopSpinner = startSpinner(
25343
+ process.stdout,
25344
+ terminal2,
25345
+ "Waiting for you to confirm in your browser\u2026"
25174
25346
  );
25347
+ try {
25348
+ return await pollForAccessToken(
25349
+ endpoints.tokenUrl,
25350
+ configuration.clientId,
25351
+ challenge.device_code,
25352
+ challenge.expires_in,
25353
+ challenge.interval
25354
+ );
25355
+ } finally {
25356
+ stopSpinner();
25357
+ }
25175
25358
  }
25176
25359
  async function enrollDevice(endpoint, accessToken, deviceName, organizationId, source) {
25177
25360
  const body = { deviceName };
@@ -25201,44 +25384,49 @@ async function enrollDevice(endpoint, accessToken, deviceName, organizationId, s
25201
25384
  );
25202
25385
  }
25203
25386
  async function chooseOrganization(organizations, hasMore) {
25204
- process.stdout.write("Choose an Iteration workspace for this collector:\n");
25205
- for (const [index, organization] of organizations.entries()) {
25206
- process.stdout.write(
25207
- index + 1 + ". " + organization.name + " (" + organization.id + ")\n"
25208
- );
25209
- }
25210
- if (hasMore) {
25211
- process.stdout.write(
25212
- "More workspaces exist; enter an organization ID to choose one not listed.\n"
25213
- );
25214
- }
25387
+ const terminal2 = terminalFor(process.stdout);
25388
+ process.stdout.write(
25389
+ [
25390
+ "",
25391
+ wrap(terminal2, "Choose a workspace for this computer", {
25392
+ style: terminal2.bold
25393
+ }),
25394
+ rows(
25395
+ terminal2,
25396
+ organizations.map((organization2, index) => [
25397
+ String(index + 1),
25398
+ `${safeWorkspaceName(organization2.name) ?? "Unnamed workspace"} ${terminal2.dim(organization2.id)}`
25399
+ ]),
25400
+ " "
25401
+ ),
25402
+ ...hasMore ? [
25403
+ wrap(
25404
+ terminal2,
25405
+ "More workspaces exist; enter a workspace ID to choose one not listed."
25406
+ )
25407
+ ] : [],
25408
+ ""
25409
+ ].join("\n")
25410
+ );
25215
25411
  if (process.stdin.isTTY !== true) {
25216
25412
  throw new Error("Run iteration interactively or pass --workspace.");
25217
25413
  }
25218
- const prompt = createInterface({
25219
- input: process.stdin,
25220
- output: process.stdout
25221
- });
25222
- try {
25223
- const answer = await prompt.question(
25224
- "Workspace number or organization ID: "
25414
+ const answer = await ask(terminal2, terminal2.bold("Workspace number or ID"));
25415
+ if (answer === null)
25416
+ throw new Error(
25417
+ "No workspace was chosen. Run iteration connect to try again."
25225
25418
  );
25226
- const id = uuid5().safeParse(answer.trim());
25227
- if (id.success) return id.data;
25228
- const selection = coerce_exports.number().int().min(1).max(organizations.length).safeParse(answer.trim());
25229
- if (!selection.success) {
25230
- throw new Error(
25231
- "Choose a listed number or enter a valid organization ID."
25232
- );
25233
- }
25234
- const organization = organizations[selection.data - 1];
25235
- if (organization === void 0) {
25236
- throw new Error("The selected workspace is not available.");
25237
- }
25238
- return organization.id;
25239
- } finally {
25240
- prompt.close();
25419
+ const id = uuid5().safeParse(answer.trim());
25420
+ if (id.success) return id.data;
25421
+ const selection = coerce_exports.number().int().min(1).max(organizations.length).safeParse(answer.trim());
25422
+ if (!selection.success) {
25423
+ throw new Error("Choose a listed number or enter a valid workspace ID.");
25424
+ }
25425
+ const organization = organizations[selection.data - 1];
25426
+ if (organization === void 0) {
25427
+ throw new Error("The selected workspace is not available.");
25241
25428
  }
25429
+ return organization.id;
25242
25430
  }
25243
25431
  async function authenticateAndEnrollCollector(endpoint, deviceNameValue, organizationId, source = "codex") {
25244
25432
  const deviceName = string5().trim().min(1).max(160).safeParse(deviceNameValue);
@@ -25453,16 +25641,15 @@ async function logout(extraDirectory) {
25453
25641
  }
25454
25642
  }
25455
25643
  await savePendingDirectories(pending, directories);
25456
- for (const source of COLLECTOR_SOURCES2) {
25457
- if (unreadableServices.has(source)) continue;
25458
- try {
25459
- await uninstallBackgroundService(source);
25460
- } catch (error3) {
25461
- failures.push(
25462
- `${source}: ${error3 instanceof Error ? error3.message : "Could not stop collector startup."}`
25463
- );
25464
- }
25465
- }
25644
+ const stopped = await Promise.all(
25645
+ COLLECTOR_SOURCES2.filter((source) => !unreadableServices.has(source)).map(
25646
+ (source) => uninstallBackgroundService(source).then(
25647
+ () => null,
25648
+ (error3) => `${source}: ${error3 instanceof Error ? error3.message : "Could not stop collector startup."}`
25649
+ )
25650
+ )
25651
+ );
25652
+ for (const failure3 of stopped) if (failure3 !== null) failures.push(failure3);
25466
25653
  for (const directory of directories) {
25467
25654
  try {
25468
25655
  await clearConnection(directory);
@@ -25751,10 +25938,10 @@ async function localAuthTurns(codexHome, modelProviders) {
25751
25938
  feedback_log_body: string5().nullable()
25752
25939
  });
25753
25940
  try {
25754
- const rows = database.prepare(
25941
+ const rows2 = database.prepare(
25755
25942
  "SELECT thread_id, feedback_log_body FROM logs WHERE target = 'feedback_tags' AND feedback_log_body LIKE '%auth_mode=Some(%'"
25756
25943
  ).iterate();
25757
- for (const raw of rows) {
25944
+ for (const raw of rows2) {
25758
25945
  const row = logRowSchema.safeParse(raw);
25759
25946
  if (!row.success)
25760
25947
  throw new Error("Codex's local log row has an invalid shape.");
@@ -26714,13 +26901,6 @@ var CODEX_APPROVAL_STEP = "Friction summary is off: in Codex, type /hooks and ap
26714
26901
  function sourceName(source) {
26715
26902
  return collectorSourceLabel(source);
26716
26903
  }
26717
- function safeWorkspaceName(value) {
26718
- const cleaned = value?.split("").map((character) => {
26719
- const code = character.charCodeAt(0);
26720
- return code < 32 || code >= 127 && code <= 159 ? " " : character;
26721
- }).join("").replace(/\s+/g, " ").trim();
26722
- return cleaned === void 0 || cleaned === "" ? null : cleaned;
26723
- }
26724
26904
  function readableBytes(bytes) {
26725
26905
  if (bytes < 1e3) return `${bytes} B`;
26726
26906
  const units = ["KB", "MB", "GB", "TB"];
@@ -26777,219 +26957,341 @@ function historyDescription(status2, source) {
26777
26957
  return "History imported; scanning current activity.";
26778
26958
  return `History imported; ${readableBytes(remainingBytes)} of new activity waiting to scan.`;
26779
26959
  }
26780
- function failureDescription(status2, source) {
26781
- const name = sourceName(source);
26960
+ function failureSummary(terminal2, status2, source, nowMs) {
26782
26961
  const failure3 = status2.health.lastFailure;
26783
26962
  if (failure3 === null) {
26784
26963
  throw new Error("A collector failure is required to describe it.");
26785
26964
  }
26786
- if (failure3.kind === "http") {
26787
- const code = failure3.status === null ? "HTTP error" : `HTTP ${failure3.status}`;
26788
- if (failure3.status === 401 || failure3.status === 403) {
26965
+ const describe2 = () => {
26966
+ if (failure3.kind === "http") {
26967
+ const code = failure3.status === null ? "HTTP error" : `HTTP ${failure3.status}`;
26968
+ if (failure3.status === 401 || failure3.status === 403)
26969
+ return {
26970
+ tone: "failure",
26971
+ headline: "Upload access needs attention",
26972
+ explanation: `Iteration denied this collector (${code}). Queued data stays on this computer. Contact Iteration support to reconnect it safely.`
26973
+ };
26974
+ if (failure3.status !== null && failure3.status < 500 && failure3.status !== 429)
26975
+ return {
26976
+ tone: "failure",
26977
+ headline: "Uploads need attention",
26978
+ explanation: `Iteration rejected an event batch (${code}). Check the collector log for details.`
26979
+ };
26789
26980
  return {
26790
- heading: `${name} upload access needs attention`,
26791
- explanation: `Iteration denied this collector (${code}). Queued data stays on this computer. Contact Iteration support to reconnect it safely.`
26981
+ tone: "warning",
26982
+ headline: "Uploads are delayed",
26983
+ explanation: `Iteration could not accept an upload (${code}). Retrying automatically.`
26792
26984
  };
26793
26985
  }
26794
- if (failure3.status !== null && failure3.status < 500 && failure3.status !== 429) {
26986
+ if (failure3.kind === "network")
26795
26987
  return {
26796
- heading: `${name} uploads need attention`,
26797
- explanation: `Iteration rejected an event batch (${code}). Check the collector log for details.`
26988
+ tone: "warning",
26989
+ headline: "Uploads are delayed",
26990
+ explanation: "Could not reach Iteration. Retrying automatically."
26991
+ };
26992
+ if (failure3.kind === "response")
26993
+ return {
26994
+ tone: "warning",
26995
+ headline: "Uploads need attention",
26996
+ explanation: "Iteration returned an unexpected upload response. Retrying automatically."
26798
26997
  };
26799
- }
26800
26998
  return {
26801
- heading: `${name} uploads are delayed`,
26802
- explanation: `Iteration could not accept an upload (${code}). Retrying automatically.`
26999
+ tone: "failure",
27000
+ headline: "Collector needs attention",
27001
+ explanation: "A local error interrupted collection."
26803
27002
  };
26804
- }
26805
- if (failure3.kind === "network") {
27003
+ };
27004
+ const { tone, headline, explanation } = describe2();
27005
+ return {
27006
+ tone,
27007
+ headline,
27008
+ facts: [],
27009
+ details: [
27010
+ explanation,
27011
+ ...status2.pendingEvents > 0 ? [`${pendingDescription(status2)}.`] : [],
27012
+ ...status2.health.lastUploadAtMs === null ? [] : [
27013
+ `Last successful upload ${relativeTime(status2.health.lastUploadAtMs, nowMs)}.`
27014
+ ]
27015
+ ],
27016
+ next: `Details: ${terminal2.bold(`iteration status ${source}`)}`
27017
+ };
27018
+ }
27019
+ function connectionSummary(terminal2, status2, source, nowMs) {
27020
+ const name = sourceName(source);
27021
+ const pending = status2.pendingEvents > 0 ? [`${pendingDescription(status2)}.`] : [];
27022
+ const details = `Details: ${terminal2.bold(`iteration status ${source}`)}`;
27023
+ if (!status2.running)
26806
27024
  return {
26807
- heading: `${name} uploads are delayed`,
26808
- explanation: "Could not reach Iteration. Retrying automatically."
27025
+ tone: "warning",
27026
+ headline: "Stopped",
27027
+ facts: [],
27028
+ details: ["New sessions are not being collected.", ...pending],
27029
+ next: `Resume with ${terminal2.bold(`iteration start ${source}`)}`
26809
27030
  };
26810
- }
26811
- if (failure3.kind === "response") {
27031
+ if (status2.hookFailureAtMs !== null && status2.hookFailureAtMs !== void 0)
26812
27032
  return {
26813
- heading: `${name} uploads need attention`,
26814
- explanation: "Iteration returned an unexpected upload response. Retrying automatically."
27033
+ tone: "warning",
27034
+ headline: "Hook capture needs attention",
27035
+ facts: [],
27036
+ details: [
27037
+ `A ${name} hook failed ${relativeTime(status2.hookFailureAtMs, nowMs)}. Some data may be missing.`
27038
+ ],
27039
+ next: details
26815
27040
  };
26816
- }
26817
- return {
26818
- heading: `${name} collector needs attention`,
26819
- explanation: `A local error interrupted collection. See iteration status ${source} for details.`
26820
- };
27041
+ if (!status2.healthAvailable)
27042
+ return {
27043
+ tone: "warning",
27044
+ headline: "Running; local status needs attention",
27045
+ facts: [],
27046
+ details: [
27047
+ "Upload history could not be read. Collection continues in the background.",
27048
+ ...pending
27049
+ ],
27050
+ next: details
27051
+ };
27052
+ if (status2.health.lastFailure !== null)
27053
+ return failureSummary(terminal2, status2, source, nowMs);
27054
+ return null;
26821
27055
  }
26822
- function renderHome(status2, nowMs = Date.now(), source = "codex") {
27056
+ function scanSummary(status2, source, nowMs) {
26823
27057
  const name = sourceName(source);
26824
- if (status2.kind === "not_connected") {
26825
- return [
26826
- "Iteration",
26827
- "",
26828
- `${name} is not connected.`,
26829
- "Run iteration connect to import your existing sessions."
26830
- ].join("\n");
26831
- }
26832
- if (status2.kind === "needs_repair") {
27058
+ const pending = status2.pendingEvents > 0 ? [`${pendingDescription(status2)}.`] : [];
27059
+ const lastUpload = status2.health.lastUploadAtMs === null ? [] : [`last upload ${relativeTime(status2.health.lastUploadAtMs, nowMs)}`];
27060
+ const summary = (headline, details, facts = []) => ({
27061
+ tone: "success",
27062
+ headline,
27063
+ facts: [...facts, ...lastUpload],
27064
+ details,
27065
+ next: null
27066
+ });
27067
+ const scan = status2.scan;
27068
+ if (scan.kind === "waiting") return summary("Preparing your history", []);
27069
+ if (scan.totalBytes > 0 && scan.scannedBytes < scan.totalBytes && status2.health.historyCaughtUpAtMs === null)
27070
+ return summary("Importing existing sessions", [
27071
+ historyDescription(status2, source),
27072
+ "New activity is collected automatically."
27073
+ ]);
27074
+ if (scan.totalBytes - scan.scannedBytes >= 1e6)
27075
+ return summary("Catching up with new activity", [
27076
+ historyDescription(status2, source),
27077
+ ...pending
27078
+ ]);
27079
+ if (status2.pendingEvents > 0)
27080
+ return summary("Uploading captured sessions", pending);
27081
+ if (scan.totalBytes === 0)
27082
+ return summary("Connected", [
27083
+ `Waiting for ${name} sessions on this computer.`
27084
+ ]);
27085
+ if (scan.scannedBytes < scan.totalBytes)
27086
+ return summary("Collecting new activity", [
27087
+ "Local history is imported; current activity is being scanned."
27088
+ ]);
27089
+ return summary("Collecting", [], ["caught up"]);
27090
+ }
27091
+ function sourceSummary(terminal2, status2, source, nowMs) {
27092
+ if (status2.kind === "not_connected")
27093
+ return {
27094
+ tone: "muted",
27095
+ headline: "Not connected",
27096
+ facts: [],
27097
+ details: [],
27098
+ next: `Run ${terminal2.bold("iteration connect")} to include it.`
27099
+ };
27100
+ if (status2.kind === "needs_repair")
27101
+ return {
27102
+ tone: "failure",
27103
+ headline: "Connection needs repair",
27104
+ facts: [],
27105
+ details: [
27106
+ "Local collector data exists, but its connection details are missing.",
27107
+ status2.pendingBytes > 0 ? `${readableBytes(status2.pendingBytes)} of queued data remains on this computer.` : "Existing local progress remains on this computer."
27108
+ ],
27109
+ next: `Run ${terminal2.bold(`iteration status ${source}`)} for recovery details.`
27110
+ };
27111
+ return connectionSummary(terminal2, status2, source, nowMs) ?? scanSummary(status2, source, nowMs);
27112
+ }
27113
+ function statusDot(terminal2, tone) {
27114
+ return terminal2.tone(
27115
+ tone,
27116
+ tone === "muted" ? terminal2.symbols.off : terminal2.symbols.on
27117
+ );
27118
+ }
27119
+ function connectedStatuses(sources) {
27120
+ return sources.flatMap(
27121
+ ({ status: status2 }) => status2.kind === "connected" ? [status2] : []
27122
+ );
27123
+ }
27124
+ function renderHome(terminal2, sources, nowMs = Date.now()) {
27125
+ const connected = connectedStatuses(sources);
27126
+ const workspaces = [
27127
+ ...new Set(
27128
+ connected.flatMap(({ workspaceName }) => {
27129
+ const name = safeWorkspaceName(workspaceName);
27130
+ return name === null ? [] : [name];
27131
+ })
27132
+ )
27133
+ ];
27134
+ const nameWidth = Math.max(
27135
+ ...sources.map(({ source }) => sourceName(source).length)
27136
+ );
27137
+ const blocks = sources.map(({ source, status: status2 }) => {
27138
+ const summary = sourceSummary(terminal2, status2, source, nowMs);
27139
+ const workspace = workspaces.length > 1 && status2.kind === "connected" ? [safeWorkspaceName(status2.workspaceName) ?? "No workspace"] : [];
27140
+ const facts = [...workspace, ...summary.facts];
27141
+ const indent = " ".repeat(4 + nameWidth + 2);
26833
27142
  return [
26834
- "Iteration",
26835
- "",
26836
- `${name} connection needs repair`,
26837
- "Local collector data exists, but its connection details are missing.",
26838
- status2.pendingBytes > 0 ? `${readableBytes(status2.pendingBytes)} of queued data remains on this computer.` : "Existing local progress remains on this computer.",
26839
- `Run iteration status ${source} for recovery details.`
26840
- ].join("\n");
26841
- }
26842
- const workspaceName = safeWorkspaceName(status2.workspaceName);
27143
+ wrap(
27144
+ terminal2,
27145
+ `${summary.headline}${facts.length === 0 ? "" : terminal2.dim(` \xB7 ${facts.join(" \xB7 ")}`)}`,
27146
+ {
27147
+ first: ` ${statusDot(terminal2, summary.tone)} ${padEnd(sourceName(source), nameWidth)} `,
27148
+ indent
27149
+ }
27150
+ ),
27151
+ ...summary.details.map(
27152
+ (line) => wrap(terminal2, line, { indent, style: terminal2.dim })
27153
+ ),
27154
+ ...summary.next === null ? [] : [wrap(terminal2, summary.next, { indent })]
27155
+ ];
27156
+ });
27157
+ const spaced = blocks.some((block) => block.length > 1);
26843
27158
  const lines = [
26844
- workspaceName === null ? "Iteration" : `Iteration \xB7 ${workspaceName}`,
26845
- ""
27159
+ brand(terminal2, workspaces.length === 1 ? workspaces[0] : null),
27160
+ "",
27161
+ ...blocks.flatMap(
27162
+ (block, index) => spaced && index > 0 ? ["", ...block] : block
27163
+ )
26846
27164
  ];
26847
- const appendConnectionStatus = () => {
26848
- if (!status2.running) {
26849
- lines.push(`${name} is stopped`, "New sessions are not being collected.");
26850
- if (status2.pendingEvents > 0)
26851
- lines.push(`${pendingDescription(status2)}.`);
26852
- lines.push(`Resume with iteration start ${source}.`);
26853
- } else if (status2.hookFailureAtMs !== null && status2.hookFailureAtMs !== void 0) {
26854
- lines.push(
26855
- `${name} hook capture needs attention`,
26856
- `A ${name} hook failed ${relativeTime(status2.hookFailureAtMs, nowMs)}. Some data may be missing. See iteration status ${source}.`
26857
- );
26858
- } else if (!status2.healthAvailable) {
26859
- lines.push(
26860
- `${name} is running; local status needs attention`,
26861
- "Upload history could not be read. Collection continues in the background."
26862
- );
26863
- if (status2.pendingEvents > 0)
26864
- lines.push(`${pendingDescription(status2)}.`);
26865
- lines.push(`Details: iteration status ${source}`);
26866
- } else if (status2.health.lastFailure !== null) {
26867
- const failure3 = failureDescription(status2, source);
26868
- lines.push(failure3.heading, failure3.explanation);
26869
- if (status2.pendingEvents > 0)
26870
- lines.push(`${pendingDescription(status2)}.`);
26871
- if (status2.health.lastUploadAtMs !== null) {
26872
- lines.push(
26873
- `Last successful upload ${relativeTime(status2.health.lastUploadAtMs, nowMs)}.`
26874
- );
26875
- }
26876
- lines.push(`Details: iteration status ${source}`);
26877
- } else return false;
26878
- return true;
26879
- };
26880
- const appendScanStatus = () => {
26881
- if (status2.scan.kind === "waiting") {
26882
- lines.push(
26883
- `${name} is preparing your history`,
26884
- progressDescription(status2.scan, source)
26885
- );
26886
- } else if (status2.scan.kind === "scanning" && status2.scan.totalBytes > 0 && status2.scan.scannedBytes < status2.scan.totalBytes && status2.health.historyCaughtUpAtMs === null) {
26887
- lines.push(
26888
- `${name} is importing existing sessions`,
26889
- historyDescription(status2, source),
26890
- "New activity is collected automatically."
26891
- );
26892
- } else if (status2.scan.kind === "scanning" && status2.scan.totalBytes - status2.scan.scannedBytes >= 1e6) {
26893
- lines.push(
26894
- `${name} is catching up with new activity`,
26895
- historyDescription(status2, source)
26896
- );
26897
- if (status2.pendingEvents > 0)
26898
- lines.push(`${pendingDescription(status2)}.`);
26899
- } else if (status2.pendingEvents > 0) {
26900
- lines.push(
26901
- `${name} is uploading captured sessions`,
26902
- `${pendingDescription(status2)}.`
26903
- );
26904
- } else if (status2.scan.totalBytes === 0) {
26905
- lines.push(
26906
- `${name} is connected`,
26907
- `Waiting for ${name} sessions on this computer.`
26908
- );
26909
- } else if (status2.scan.kind === "scanning" && status2.scan.scannedBytes < status2.scan.totalBytes) {
26910
- lines.push(
26911
- `${name} is collecting new activity`,
26912
- "Local history is imported; current activity is being scanned."
26913
- );
26914
- } else {
26915
- lines.push(
26916
- `${name} is collecting`,
26917
- "Local scan is caught up and no uploads are waiting.",
26918
- "New activity is collected automatically."
26919
- );
26920
- }
26921
- };
26922
- if (!appendConnectionStatus()) appendScanStatus();
26923
- const appendLastUpload = () => {
26924
- if (status2.running && status2.health.lastFailure === null && status2.health.lastUploadAtMs !== null) {
26925
- lines.push(
26926
- `Last successful upload ${relativeTime(status2.health.lastUploadAtMs, nowMs)}.`
26927
- );
26928
- }
26929
- };
26930
- appendLastUpload();
26931
- if (status2.turnSummaryNeedsApproval) lines.push("", CODEX_APPROVAL_STEP);
26932
- lines.push("", `Explore traces ${status2.tracesUrl}`);
27165
+ if (connected.some((status2) => status2.turnSummaryNeedsApproval))
27166
+ lines.push("", mark(terminal2, "warning", CODEX_APPROVAL_STEP, " "));
27167
+ const links = [...new Set(connected.map(({ tracesUrl: tracesUrl2 }) => tracesUrl2))];
27168
+ if (links.length > 0)
27169
+ lines.push(
27170
+ "",
27171
+ ...links.map((url2) => ` Open Iteration ${terminal2.link(url2)}`)
27172
+ );
26933
27173
  return lines.join("\n");
26934
27174
  }
26935
- function renderDetailedStatus(status2, nowMs = Date.now(), source = "codex") {
27175
+ function sourceHeading(terminal2, tone, source, note) {
27176
+ return `${statusDot(terminal2, tone)} ${terminal2.bold(sourceName(source))}${note === null ? "" : terminal2.dim(` \xB7 ${note}`)}`;
27177
+ }
27178
+ function sentenceCase(text) {
27179
+ return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
27180
+ }
27181
+ function renderDetailedStatus(terminal2, source, status2, nowMs = Date.now()) {
26936
27182
  const name = sourceName(source);
26937
27183
  if (status2.kind === "not_connected") {
26938
- return `${name} is not connected. Run iteration connect to connect.`;
27184
+ return [
27185
+ sourceHeading(terminal2, "muted", source, "not connected"),
27186
+ wrap(terminal2, `Run ${terminal2.bold("iteration connect")} to connect.`)
27187
+ ].join("\n");
26939
27188
  }
26940
27189
  if (status2.kind === "needs_repair") {
26941
27190
  return [
26942
- `${name} connection needs repair`,
26943
- "Local collector data exists without its connection details.",
26944
- `Queued data: ${readableBytes(status2.pendingBytes)}`,
26945
- `Restore the missing config from backup: ${status2.configPath}`,
26946
- "If you do not have it, contact Iteration support before reconnecting; existing data has been kept."
27191
+ sourceHeading(terminal2, "failure", source, "connection needs repair"),
27192
+ wrap(
27193
+ terminal2,
27194
+ "Local collector data exists without its connection details."
27195
+ ),
27196
+ rows(terminal2, [["Queued data", readableBytes(status2.pendingBytes)]]),
27197
+ wrap(
27198
+ terminal2,
27199
+ `Restore the missing config from backup: ${status2.configPath}`
27200
+ ),
27201
+ wrap(
27202
+ terminal2,
27203
+ "If you do not have it, contact Iteration support before reconnecting; existing data has been kept."
27204
+ )
26947
27205
  ].join("\n");
26948
27206
  }
26949
- const workspaceName = safeWorkspaceName(status2.workspaceName);
26950
- const lines = [
26951
- `${name} collector`,
26952
- ...workspaceName === null ? [] : [`Workspace: ${workspaceName}`],
26953
- `Background process: ${status2.running ? "Running" : "Stopped"}`,
26954
- `History: ${historyDescription(status2, source).replace(/^History /, "")}`,
26955
- `Uploads: ${status2.pendingEvents === 0 ? "None waiting" : pendingDescription(status2)}`
27207
+ const summary = sourceSummary(terminal2, status2, source, nowMs);
27208
+ const entries2 = [
27209
+ ["Background process", status2.running ? "Running" : "Stopped"],
27210
+ [
27211
+ "History",
27212
+ sentenceCase(historyDescription(status2, source).replace(/^History /, ""))
27213
+ ],
27214
+ [
27215
+ "Uploads",
27216
+ status2.pendingEvents === 0 ? "None waiting" : sentenceCase(pendingDescription(status2))
27217
+ ]
26956
27218
  ];
26957
- if (!status2.healthAvailable) {
26958
- lines.push(
26959
- "Local status: unavailable; check collector file permissions",
26960
- `Collector log: ${status2.logPath}`
26961
- );
26962
- }
26963
- if (status2.health.lastUploadAtMs !== null) {
26964
- lines.push(
26965
- `Last successful upload: ${relativeTime(status2.health.lastUploadAtMs, nowMs)}`
26966
- );
26967
- }
26968
- if (status2.health.lastFailure !== null) {
26969
- const failure3 = status2.health.lastFailure;
27219
+ if (!status2.healthAvailable)
27220
+ entries2.push([
27221
+ "Local status",
27222
+ "Unavailable; check collector file permissions"
27223
+ ]);
27224
+ if (status2.health.lastUploadAtMs !== null)
27225
+ entries2.push([
27226
+ "Last upload",
27227
+ relativeTime(status2.health.lastUploadAtMs, nowMs)
27228
+ ]);
27229
+ const failure3 = status2.health.lastFailure;
27230
+ if (failure3 !== null) {
26970
27231
  const label2 = failure3.kind === "http" && failure3.status !== null ? `HTTP ${failure3.status}` : failure3.kind === "network" ? "Network unavailable" : failure3.kind === "response" ? "Unexpected upload response" : "Local collector error";
26971
- lines.push(
26972
- `Last issue: ${label2} (${relativeTime(failure3.atMs, nowMs)})`,
26973
- `Collector log: ${status2.logPath}`
26974
- );
27232
+ entries2.push([
27233
+ "Last issue",
27234
+ `${label2} (${relativeTime(failure3.atMs, nowMs)})`
27235
+ ]);
26975
27236
  }
26976
27237
  if (status2.hookFailureAtMs !== null && status2.hookFailureAtMs !== void 0)
27238
+ entries2.push([
27239
+ "Hook capture",
27240
+ `Failed ${relativeTime(status2.hookFailureAtMs, nowMs)}. Some data may be missing; inspect ${name} hook logs.`
27241
+ ]);
27242
+ if (!status2.healthAvailable || failure3 !== null)
27243
+ entries2.push(["Collector log", status2.logPath]);
27244
+ entries2.push(["Open Iteration", terminal2.link(status2.tracesUrl)]);
27245
+ const lines = [
27246
+ sourceHeading(
27247
+ terminal2,
27248
+ summary.tone,
27249
+ source,
27250
+ safeWorkspaceName(status2.workspaceName)
27251
+ ),
27252
+ rows(terminal2, entries2)
27253
+ ];
27254
+ if (status2.turnSummaryNeedsApproval)
27255
+ lines.push(mark(terminal2, "warning", CODEX_APPROVAL_STEP, " "));
27256
+ if (!status2.running)
26977
27257
  lines.push(
26978
- `Last ${name} hook capture failure: ${relativeTime(status2.hookFailureAtMs, nowMs)}. Some data may be missing; inspect ${name} hook logs.`
27258
+ wrap(
27259
+ terminal2,
27260
+ `Resume with ${terminal2.bold(`iteration start ${source}`)}`
27261
+ )
26979
27262
  );
26980
- if (status2.turnSummaryNeedsApproval) lines.push(CODEX_APPROVAL_STEP);
26981
- if (!status2.running) lines.push(`Resume: iteration start ${source}`);
26982
- lines.push(`Explore traces: ${status2.tracesUrl}`);
26983
27263
  return lines.join("\n");
26984
27264
  }
26985
- function renderRuntime(summary) {
27265
+ function renderRuntime(terminal2, summary) {
26986
27266
  return [
26987
- `Iteration ${summary.version} \xB7 ${summary.autoUpdate ? "updates automatically" : "automatic updates are off; run iteration update to update"}`,
26988
- ...summary.confirming === null ? [] : [`Starting version ${summary.confirming} after an update.`],
27267
+ wrap(
27268
+ terminal2,
27269
+ `Version ${summary.version} \xB7 ${summary.autoUpdate ? "updates automatically" : "automatic updates are off; run iteration update to update"}`,
27270
+ { style: terminal2.dim }
27271
+ ),
27272
+ ...summary.confirming === null ? [] : [
27273
+ wrap(
27274
+ terminal2,
27275
+ `Starting version ${summary.confirming} after an update.`,
27276
+ { style: terminal2.dim }
27277
+ )
27278
+ ],
26989
27279
  ...summary.rolledBack === null ? [] : [
26990
- `Version ${summary.rolledBack.version} was rolled back: ${summary.rolledBack.reason}`
27280
+ mark(
27281
+ terminal2,
27282
+ "warning",
27283
+ `Version ${summary.rolledBack.version} was rolled back: ${summary.rolledBack.reason}`,
27284
+ " "
27285
+ )
26991
27286
  ],
26992
- ...summary.checkError === null ? [] : [`Last update check failed: ${summary.checkError}`]
27287
+ ...summary.checkError === null ? [] : [
27288
+ mark(
27289
+ terminal2,
27290
+ "warning",
27291
+ `Last update check failed: ${summary.checkError}`,
27292
+ " "
27293
+ )
27294
+ ]
26993
27295
  ].join("\n");
26994
27296
  }
26995
27297
 
@@ -27101,6 +27403,14 @@ async function superviseCollector(source, dataDirectory2) {
27101
27403
 
27102
27404
  // src/cli.ts
27103
27405
  var DEFAULT_INGEST_ENDPOINT = "https://useiteration.com/api/traces/ingest";
27406
+ var terminal = terminalFor(process.stdout);
27407
+ function print(...lines) {
27408
+ process.stdout.write(`${lines.join("\n")}
27409
+ `);
27410
+ }
27411
+ function tracesUrl(endpoint) {
27412
+ return new URL("/app/sessions", endpoint).toString();
27413
+ }
27104
27414
  function argumentsForCli() {
27105
27415
  const parsed = parseArgs({
27106
27416
  args: process.argv.slice(2),
@@ -27141,55 +27451,95 @@ function optionalString(values, name) {
27141
27451
  return parsed.data;
27142
27452
  }
27143
27453
  function usage(command) {
27454
+ const section = (title, entries2) => [
27455
+ wrap(terminal, title, { style: terminal.bold }),
27456
+ rows(terminal, entries2, " ")
27457
+ ];
27144
27458
  if (command === "logout") {
27145
- process.stdout.write(
27146
- "Sign out of Iteration on this computer\n iteration logout\n\nStops all collectors and removes saved credentials and automatic connection approval.\nLocal pending data is archived and will not be uploaded after reconnecting.\nAgent session files and previously uploaded data are kept.\n\n --data-directory DIR Also clear a custom collector directory with no installed service\n\nRun iteration connect to sign in again.\n"
27459
+ print(
27460
+ brand(terminal),
27461
+ "",
27462
+ ...section("Sign out of Iteration on this computer", [
27463
+ ["iteration logout", ""]
27464
+ ]),
27465
+ "",
27466
+ wrap(
27467
+ terminal,
27468
+ "Stops all collectors and removes saved credentials and automatic connection approval. Local pending data is archived and will not be uploaded after reconnecting. Agent session files and previously uploaded data are kept."
27469
+ ),
27470
+ "",
27471
+ ...section("Options", [
27472
+ [
27473
+ "--data-directory DIR",
27474
+ "Also clear a custom collector directory with no installed service"
27475
+ ]
27476
+ ]),
27477
+ "",
27478
+ wrap(
27479
+ terminal,
27480
+ `Run ${terminal.bold("iteration connect")} to sign in again.`
27481
+ )
27147
27482
  );
27148
27483
  return;
27149
27484
  }
27150
27485
  if (command === "connect") {
27151
- process.stdout.write(
27152
- [
27153
- "Connect a coding agent to Iteration",
27154
- " iteration connect Connect all detected agents on this computer",
27155
- " iteration connect codex",
27156
- " iteration connect claude",
27157
- " iteration connect cursor",
27158
- "",
27159
- "Existing local sessions and new activity are collected automatically.",
27160
- "",
27161
- "Options for advanced setups:",
27162
- " --device-name NAME Name this computer in Iteration",
27163
- " --workspace ID Connect to this workspace without a prompt",
27164
- " --codex-home DIR Use a different Codex data directory",
27165
- " --claude-home DIR Use a different Claude data directory",
27166
- " --cursor-home DIR Use a different Cursor data directory",
27167
- " --yes Approve uploads without a terminal prompt",
27168
- " --data-directory DIR Use a different state directory with a source-specific command",
27169
- " --endpoint URL Use a different Iteration server"
27170
- ].join("\n") + "\n"
27171
- );
27172
- return;
27173
- }
27174
- process.stdout.write(
27175
- [
27176
- "Iteration CLI",
27486
+ print(
27487
+ brand(terminal),
27177
27488
  "",
27178
- "Get started:",
27179
- " iteration connect Connect detected agents and import sessions",
27489
+ ...section("Connect coding agents", [
27490
+ ["iteration connect", "Connect all detected agents on this computer"],
27491
+ [
27492
+ "iteration connect <agent>",
27493
+ "Connect one agent: codex, claude or cursor"
27494
+ ]
27495
+ ]),
27180
27496
  "",
27181
- "Commands:",
27182
- " iteration See connection status",
27183
- " iteration status See scan, upload, and error details",
27184
- " iteration connect codex|claude|cursor Connect one source (advanced)",
27185
- " iteration disconnect codex|claude|cursor Stop a source",
27186
- " iteration logout Sign out and stop all sources on this computer",
27187
- " iteration update Update now (updates also install automatically)",
27188
- " iteration update off|on Turn automatic updates off or on",
27189
- " iteration version Show the installed version",
27497
+ wrap(
27498
+ terminal,
27499
+ "Existing local sessions and new activity are collected automatically."
27500
+ ),
27190
27501
  "",
27191
- "Run iteration connect --help for advanced setup options."
27192
- ].join("\n") + "\n"
27502
+ ...section("Options for advanced setups", [
27503
+ ["--device-name NAME", "Name this computer in Iteration"],
27504
+ ["--workspace ID", "Connect to this workspace without a prompt"],
27505
+ ["--codex-home DIR", "Use a different Codex data directory"],
27506
+ ["--claude-home DIR", "Use a different Claude data directory"],
27507
+ ["--cursor-home DIR", "Use a different Cursor data directory"],
27508
+ ["--yes", "Approve uploads without a terminal prompt"],
27509
+ [
27510
+ "--data-directory DIR",
27511
+ "Use a different state directory with a one-agent command"
27512
+ ],
27513
+ ["--endpoint URL", "Use a different Iteration server"]
27514
+ ])
27515
+ );
27516
+ return;
27517
+ }
27518
+ print(
27519
+ brand(terminal),
27520
+ "",
27521
+ ...section("Get started", [
27522
+ ["iteration connect", "Connect detected agents and import sessions"]
27523
+ ]),
27524
+ "",
27525
+ ...section("Commands", [
27526
+ ["iteration", "See connection status"],
27527
+ ["iteration status", "See scan, upload and error details"],
27528
+ [
27529
+ "iteration connect <agent>",
27530
+ "Connect one agent: codex, claude or cursor"
27531
+ ],
27532
+ ["iteration disconnect <agent>", "Stop one agent"],
27533
+ ["iteration logout", "Sign out and stop all sources on this computer"],
27534
+ ["iteration update", "Update now; updates also install automatically"],
27535
+ ["iteration update off|on", "Turn automatic updates off or on"],
27536
+ ["iteration version", "Show the installed version"]
27537
+ ]),
27538
+ "",
27539
+ wrap(
27540
+ terminal,
27541
+ `Run ${terminal.bold("iteration connect --help")} for advanced setup options.`
27542
+ )
27193
27543
  );
27194
27544
  }
27195
27545
  async function fileExists(filename) {
@@ -27212,29 +27562,20 @@ async function defaultCommand() {
27212
27562
  snapshot: await statusSnapshot(source, {})
27213
27563
  }))
27214
27564
  );
27215
- const connected = snapshots.filter(
27216
- ({ snapshot }) => snapshot.kind !== "not_connected"
27217
- );
27218
- if (connected.length > 0) {
27219
- process.stdout.write(
27220
- `${connected.map(({ source, snapshot }) => renderHome(snapshot, Date.now(), source)).join("\n\n")}
27221
- `
27222
- );
27565
+ if (snapshots.some(({ snapshot }) => snapshot.kind !== "not_connected")) {
27223
27566
  const discovered = await detectedSources({
27224
27567
  codex: sourceHome("codex"),
27225
27568
  claude: sourceHome("claude"),
27226
27569
  cursor: sourceHome("cursor")
27227
27570
  });
27228
- const missing2 = discovered.filter(
27229
- (source) => snapshots.find((item) => item.source === source)?.snapshot.kind === "not_connected"
27571
+ print(
27572
+ renderHome(
27573
+ terminal,
27574
+ snapshots.flatMap(
27575
+ ({ source, snapshot }) => snapshot.kind !== "not_connected" || discovered.includes(source) ? [{ source, status: snapshot }] : []
27576
+ )
27577
+ )
27230
27578
  );
27231
- if (missing2.length > 0) {
27232
- process.stdout.write(
27233
- `
27234
- ${missing2.map(collectorSourceLabel).join(" and ")} found on this computer but not connected. Run iteration connect to include ${missing2.length === 1 ? "it" : "them"}.
27235
- `
27236
- );
27237
- }
27238
27579
  return;
27239
27580
  }
27240
27581
  if (process.stdin.isTTY !== true || process.stdout.isTTY !== true) {
@@ -27248,19 +27589,78 @@ function dataDirectory(source, values) {
27248
27589
  optionalString(values, "data-directory") ?? defaultCollectorDirectory(source)
27249
27590
  );
27250
27591
  }
27251
- async function turnSummaryNotice(config3) {
27252
- if ("cursorHome" in config3)
27253
- return " Cursor hooks capture tool results and usage automatically.";
27592
+ async function setUpTurnSummary(config3) {
27593
+ if ("cursorHome" in config3) return { kind: "unsupported" };
27254
27594
  try {
27255
27595
  await installTurnSummary(config3);
27256
- if (await codexTurnSummaryApproval(config3) === "needs_approval") {
27257
- return "\nOne more step: in Codex, type /hooks and approve Iteration to see your friction summary after each turn.";
27258
- }
27259
- return " A one-line friction summary now appears after agent turns in your repositories.";
27596
+ return await codexTurnSummaryApproval(config3) === "needs_approval" ? { kind: "needs_approval" } : { kind: "ready" };
27260
27597
  } catch (error3) {
27261
- return ` The turn summary could not be installed: ${error3 instanceof Error ? error3.message : "unknown error"} Run iteration start ${collectorSource(config3)} to retry it.`;
27598
+ return {
27599
+ kind: "failed",
27600
+ reason: error3 instanceof Error ? error3.message : "unknown error"
27601
+ };
27262
27602
  }
27263
27603
  }
27604
+ function turnSummaryLines(results) {
27605
+ const warnings = results.flatMap(({ source, turnSummary }) => {
27606
+ const name = collectorSourceLabel(source);
27607
+ if (turnSummary.kind === "needs_approval")
27608
+ return [
27609
+ mark(
27610
+ terminal,
27611
+ "warning",
27612
+ `${terminal.bold(`One more step for ${name}:`)} type /hooks in ${name} and approve Iteration to see your friction summary after each turn.`
27613
+ )
27614
+ ];
27615
+ if (turnSummary.kind === "failed")
27616
+ return [
27617
+ mark(
27618
+ terminal,
27619
+ "warning",
27620
+ `The ${name} friction summary could not be installed: ${turnSummary.reason} Run ${terminal.bold(`iteration start ${source}`)} to retry it.`
27621
+ )
27622
+ ];
27623
+ return [];
27624
+ });
27625
+ return [
27626
+ ...results.some(({ turnSummary }) => turnSummary.kind === "ready") ? [
27627
+ wrap(
27628
+ terminal,
27629
+ "A one-line friction summary now appears after agent turns in your repositories."
27630
+ )
27631
+ ] : [],
27632
+ ...warnings
27633
+ ];
27634
+ }
27635
+ var CONNECTED_WIDTH = Math.max(
27636
+ ...COLLECTOR_SOURCES2.map(
27637
+ (source) => `${collectorSourceLabel(source)} connected`.length
27638
+ )
27639
+ );
27640
+ function connectedLine(source, sessions) {
27641
+ return mark(
27642
+ terminal,
27643
+ "success",
27644
+ `${padEnd(`${collectorSourceLabel(source)} connected`, CONNECTED_WIDTH)} ${terminal.dim(
27645
+ sessions === 0 ? "no saved sessions yet" : `importing ${sessions.toLocaleString("en-US")} ${sessions === 1 ? "session" : "sessions"}`
27646
+ )}`
27647
+ );
27648
+ }
27649
+ function connectionSummary2(results, imported) {
27650
+ const links = [
27651
+ ...new Set(results.map(({ endpoint }) => tracesUrl(endpoint)))
27652
+ ];
27653
+ const notes = turnSummaryLines(results);
27654
+ return [
27655
+ ...notes.length === 0 ? [] : ["", ...notes],
27656
+ "",
27657
+ wrap(
27658
+ terminal,
27659
+ imported ? `Sessions import newest first. Run ${terminal.bold("iteration")} to follow progress.` : `Run ${terminal.bold("iteration")} to see their status.`
27660
+ ),
27661
+ ...links.map((url2) => ` Open Iteration ${terminal.link(url2)}`)
27662
+ ];
27663
+ }
27264
27664
  async function initialize(source, values) {
27265
27665
  requireCollectorPlatform();
27266
27666
  const endpoint = optionalString(values, "endpoint") ?? DEFAULT_INGEST_ENDPOINT;
@@ -27285,6 +27685,13 @@ async function initialize(source, values) {
27285
27685
  organizationId,
27286
27686
  source
27287
27687
  );
27688
+ print(
27689
+ mark(
27690
+ terminal,
27691
+ "success",
27692
+ `Signed in to ${terminal.bold(safeWorkspaceName(enrollment.organizationName) ?? "your workspace")}`
27693
+ )
27694
+ );
27288
27695
  const connection = {
27289
27696
  endpoint: endpointUrl.toString(),
27290
27697
  token: enrollment.token,
@@ -27311,22 +27718,40 @@ async function initialize(source, values) {
27311
27718
  { cause: error3 }
27312
27719
  );
27313
27720
  }
27314
- const notice = await turnSummaryNotice(config3);
27315
- process.stdout.write(
27316
- `${collectorSourceLabel(source)} is connected to ${enrollment.organizationName}. Existing sessions are importing, newest first, and new activity is collected automatically. Iteration shows the import as it runs.${notice}
27317
- `
27318
- );
27319
- return config3;
27721
+ const turnSummary = await setUpTurnSummary(config3);
27722
+ print(connectedLine(source, await countSavedSessions(source, selectedHome)));
27723
+ return {
27724
+ config: config3,
27725
+ result: { source, endpoint: config3.endpoint, turnSummary }
27726
+ };
27320
27727
  }
27321
27728
  async function approveAllSources(sources, workspaceName, yes) {
27322
- const names = sources.map(
27323
- ({ source, sessions }) => `${collectorSourceLabel(source)} (${sessions.toLocaleString("en-US")} saved ${sessions === 1 ? "session" : "sessions"})`
27324
- ).join(" and ");
27325
27729
  const safeName = safeWorkspaceName(workspaceName);
27326
- process.stdout.write(
27327
- `Detected ${names || "no saved agent sessions"} on this computer.
27328
- Connect supported agents${safeName ? ` to ${safeName}` : " to the workspace you select"}? Existing sessions and future activity, including prompts, code, and tool output, will be uploaded. Workspace members can read them. Newly detected supported agents will connect automatically.${process.platform === "linux" ? " Collection will continue after you log out." : ""}
27329
- `
27730
+ print(
27731
+ wrap(
27732
+ terminal,
27733
+ sources.length === 0 ? "No saved agent sessions found on this computer" : `Found ${sources.length} coding ${sources.length === 1 ? "agent" : "agents"} on this computer`,
27734
+ { style: terminal.bold }
27735
+ ),
27736
+ ...sources.length === 0 ? [] : [
27737
+ "",
27738
+ rows(
27739
+ terminal,
27740
+ sources.map(({ source, sessions }) => [
27741
+ collectorSourceLabel(source),
27742
+ terminal.dim(
27743
+ `${sessions.toLocaleString("en-US")} saved ${sessions === 1 ? "session" : "sessions"}`
27744
+ )
27745
+ ]),
27746
+ " "
27747
+ )
27748
+ ],
27749
+ "",
27750
+ wrap(
27751
+ terminal,
27752
+ `Existing sessions and new activity, including prompts, code and tool output, upload to ${safeName ?? "your workspace"}, where its members can read them. Supported agents you install later connect automatically.${process.platform === "linux" ? " Collection continues after you log out." : ""}`
27753
+ ),
27754
+ ""
27330
27755
  );
27331
27756
  if (yes) return;
27332
27757
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
@@ -27334,17 +27759,15 @@ Connect supported agents${safeName ? ` to ${safeName}` : " to the workspace you
27334
27759
  "Run iteration connect interactively or pass --yes to approve uploads."
27335
27760
  );
27336
27761
  }
27337
- const prompt = createInterface2({
27338
- input: process.stdin,
27339
- output: process.stdout
27340
- });
27341
- try {
27342
- const answer = (await prompt.question("Connect agents? [y/N] ")).trim().toLowerCase();
27343
- if (answer !== "y" && answer !== "yes")
27344
- throw new Error("No agents were connected.");
27345
- } finally {
27346
- prompt.close();
27347
- }
27762
+ const answer = await ask(
27763
+ terminal,
27764
+ `${terminal.bold(sources.length === 1 ? "Connect this agent?" : "Connect these agents?")} ${terminal.dim("(y/N)")}`
27765
+ );
27766
+ const approved = answer?.trim().toLowerCase();
27767
+ if (approved !== "y" && approved !== "yes")
27768
+ throw new Error(
27769
+ "No agents were connected. Run iteration connect when you are ready."
27770
+ );
27348
27771
  }
27349
27772
  async function connectAll(values) {
27350
27773
  requireCollectorPlatform();
@@ -27370,12 +27793,23 @@ async function connectAll(values) {
27370
27793
  const existing = COLLECTOR_SOURCES2.flatMap(
27371
27794
  (source, index) => configs[index] ? [{ source, config: configs[index] }] : []
27372
27795
  );
27796
+ print(brand(terminal), "");
27373
27797
  if (detected.length === 0 && existing.length === 0) {
27374
- process.stdout.write(
27375
- "No supported local coding agents found yet. Run iteration connect after using Codex, Claude Code, or Cursor on this computer.\n"
27798
+ print(
27799
+ mark(terminal, "warning", "No supported local coding agents found yet"),
27800
+ wrap(
27801
+ terminal,
27802
+ `Run ${terminal.bold("iteration connect")} after using Codex, Claude Code or Cursor on this computer.`
27803
+ )
27376
27804
  );
27377
27805
  return;
27378
27806
  }
27807
+ const sessions = await Promise.all(
27808
+ detected.map(async (source) => ({
27809
+ source,
27810
+ sessions: await countSavedSessions(source, sourceHomes[source])
27811
+ }))
27812
+ );
27379
27813
  const anchorSource = existing[0]?.source ?? detected[0];
27380
27814
  const anchorExisting = existing[0]?.config ?? null;
27381
27815
  const endpoint = validateCollectorEndpoint(
@@ -27414,12 +27848,7 @@ async function connectAll(values) {
27414
27848
  const needsApproval = () => previousConsent === null || anchorExisting === null || previousConsent.endpoint !== endpoint || previousConsent.anchorSource !== anchorSource || previousConsent.anchorDataDirectory !== anchorExisting.dataDirectory || previousConsent.organizationId !== existingScopes[0]?.scope.organizationId || previousConsent.sourceHomes.codex !== sourceHomes.codex || previousConsent.sourceHomes.claude !== sourceHomes.claude || previousConsent.sourceHomes.cursor !== sourceHomes.cursor;
27415
27849
  if (needsApproval()) {
27416
27850
  await approveAllSources(
27417
- await Promise.all(
27418
- detected.map(async (source) => ({
27419
- source,
27420
- sessions: await countSavedSessions(source, sourceHomes[source])
27421
- }))
27422
- ),
27851
+ sessions,
27423
27852
  existingScopes[0]?.scope.organizationName ?? null,
27424
27853
  values.yes === true
27425
27854
  );
@@ -27427,7 +27856,13 @@ async function connectAll(values) {
27427
27856
  };
27428
27857
  await approveConnection();
27429
27858
  await prepareBackgroundPersistence();
27430
- let anchor3 = anchorExisting ?? await initialize(anchorSource, values);
27859
+ const results = [];
27860
+ const initializeAnchor = async () => {
27861
+ const initialized = await initialize(anchorSource, values);
27862
+ results.push(initialized.result);
27863
+ return initialized.config;
27864
+ };
27865
+ let anchor3 = anchorExisting ?? await initializeAnchor();
27431
27866
  let organizationId = requestedOrganizationId ?? existingScopes[0]?.scope.organizationId ?? anchor3.organizationId ?? null;
27432
27867
  const connectDetectedSources = async () => {
27433
27868
  for (const source of detected) {
@@ -27449,10 +27884,16 @@ async function connectAll(values) {
27449
27884
  state
27450
27885
  );
27451
27886
  organizationId = enrollment.organizationId;
27452
- const notice = await turnSummaryNotice(config3);
27453
- process.stdout.write(
27454
- `${collectorSourceLabel(source)} is connected to ${enrollment.organizationName}.${notice}
27455
- `
27887
+ results.push({
27888
+ source,
27889
+ endpoint: config3.endpoint,
27890
+ turnSummary: await setUpTurnSummary(config3)
27891
+ });
27892
+ print(
27893
+ connectedLine(
27894
+ source,
27895
+ sessions.find((item) => item.source === source)?.sessions ?? 0
27896
+ )
27456
27897
  );
27457
27898
  }
27458
27899
  };
@@ -27483,15 +27924,20 @@ async function connectAll(values) {
27483
27924
  item.config.dataDirectory
27484
27925
  );
27485
27926
  await installBackgroundService(item.config.dataDirectory, item.source);
27486
- const notice = await turnSummaryNotice(item.config);
27487
- process.stdout.write(
27488
- `${collectorSourceLabel(item.source)} is still connected.${notice}
27489
- `
27927
+ results.push({
27928
+ source: item.source,
27929
+ endpoint: item.config.endpoint,
27930
+ turnSummary: await setUpTurnSummary(item.config)
27931
+ });
27932
+ print(
27933
+ mark(
27934
+ terminal,
27935
+ "success",
27936
+ `${collectorSourceLabel(item.source)} is still connected`
27937
+ )
27490
27938
  );
27491
27939
  }
27492
- process.stdout.write(
27493
- "Detected agents are connected. New supported agents on this computer will connect automatically.\n"
27494
- );
27940
+ print(...connectionSummary2(results, results.length > existing.length));
27495
27941
  }
27496
27942
  async function importHistory(source, values) {
27497
27943
  requireCollectorPlatform();
@@ -27502,22 +27948,47 @@ async function importHistory(source, values) {
27502
27948
  throw new Error(
27503
27949
  `This collector directory belongs to ${collectorSource(config3)}.`
27504
27950
  );
27951
+ const name = collectorSourceLabel(source);
27505
27952
  const estimate = (await importSourceHistory(config3, paths, false)).size;
27506
- process.stdout.write(
27507
- `Found ${estimate.files} local ${source} session files (${estimate.bytes} bytes). History may include prompts, code, and tool output that workspace members can read.
27508
- `
27953
+ print(
27954
+ wrap(
27955
+ terminal,
27956
+ `Found ${estimate.files.toLocaleString("en-US")} local ${name} session files (${readableBytes(estimate.bytes)})`,
27957
+ { indent: "", style: terminal.bold }
27958
+ ),
27959
+ wrap(
27960
+ terminal,
27961
+ "History may include prompts, code and tool output that workspace members can read."
27962
+ )
27509
27963
  );
27510
27964
  if (values.yes !== true) {
27511
- process.stdout.write(
27512
- `No changes made. Run iteration import-history ${source} --yes to confirm this upload.
27513
- `
27965
+ print(
27966
+ mark(
27967
+ terminal,
27968
+ "warning",
27969
+ `No changes made. Run ${terminal.bold(`iteration import-history ${source} --yes`)} to confirm this upload.`
27970
+ )
27514
27971
  );
27515
27972
  return;
27516
27973
  }
27517
27974
  const result = await importSourceHistory(config3, paths, true);
27518
- process.stdout.write(
27519
- `History scan scheduled for ${result.size.files} local session files (${result.size.bytes} bytes). Scanning and uploads run in bounded batches and may take time. Older sessions appear under the date Iteration receives them. Use iteration status ${source} to see local scan progress and pending uploads.${result.backgroundRunning ? "" : ` The collector was not running; run iteration start ${source} to begin scanning.`}
27520
- `
27975
+ print(
27976
+ mark(
27977
+ terminal,
27978
+ "success",
27979
+ `History scan scheduled for ${result.size.files.toLocaleString("en-US")} local session files (${readableBytes(result.size.bytes)})`
27980
+ ),
27981
+ wrap(
27982
+ terminal,
27983
+ `Scanning and uploads run in bounded batches and may take time. Older sessions appear under the date Iteration receives them. Run ${terminal.bold(`iteration status ${source}`)} to see local scan progress and pending uploads.`
27984
+ ),
27985
+ ...result.backgroundRunning ? [] : [
27986
+ mark(
27987
+ terminal,
27988
+ "warning",
27989
+ `The collector was not running. Run ${terminal.bold(`iteration start ${source}`)} to begin scanning.`
27990
+ )
27991
+ ]
27521
27992
  );
27522
27993
  }
27523
27994
  async function start(source, values) {
@@ -27533,10 +28004,20 @@ async function start(source, values) {
27533
28004
  if ("cursorHome" in config3)
27534
28005
  await installCursorHooks(config3.cursorHome, config3.dataDirectory);
27535
28006
  await installBackgroundService(directory, source);
27536
- const notice = await turnSummaryNotice(config3);
27537
- process.stdout.write(
27538
- `${collectorSourceLabel(source)} is collecting again. Run iteration to check progress.${repairedState ? " Incomplete setup was repaired." : ""}${notice}
27539
- `
28007
+ const turnSummary = await setUpTurnSummary(config3);
28008
+ print(
28009
+ mark(
28010
+ terminal,
28011
+ "success",
28012
+ `${collectorSourceLabel(source)} is collecting again`
28013
+ ),
28014
+ ...repairedState ? [
28015
+ wrap(terminal, "Incomplete setup was repaired.", {
28016
+ style: terminal.dim
28017
+ })
28018
+ ] : [],
28019
+ ...turnSummaryLines([{ source, endpoint: config3.endpoint, turnSummary }]),
28020
+ wrap(terminal, `Run ${terminal.bold("iteration")} to check progress.`)
27540
28021
  );
27541
28022
  }
27542
28023
  async function statusSnapshot(source, values) {
@@ -27578,16 +28059,18 @@ async function statusSnapshot(source, values) {
27578
28059
  healthAvailable: localHealth.kind === "available",
27579
28060
  turnSummaryNeedsApproval: approval === "needs_approval",
27580
28061
  hookFailureAtMs,
27581
- tracesUrl: new URL("/app/sessions", config3.endpoint).toString(),
28062
+ tracesUrl: tracesUrl(config3.endpoint),
27582
28063
  logPath: collectorLogPath(source)
27583
28064
  };
27584
28065
  }
27585
28066
  async function status(source, values) {
27586
28067
  if (source !== void 0) {
27587
- const snapshot = await statusSnapshot(source, values);
27588
- process.stdout.write(
27589
- `${renderDetailedStatus(snapshot, Date.now(), source)}
27590
- `
28068
+ print(
28069
+ renderDetailedStatus(
28070
+ terminal,
28071
+ source,
28072
+ await statusSnapshot(source, values)
28073
+ )
27591
28074
  );
27592
28075
  return;
27593
28076
  }
@@ -27597,9 +28080,10 @@ async function status(source, values) {
27597
28080
  snapshot: await statusSnapshot(item, values)
27598
28081
  }))
27599
28082
  );
27600
- process.stdout.write(
27601
- `${snapshots.map(({ source: item, snapshot }) => renderDetailedStatus(snapshot, Date.now(), item)).join("\n\n")}
27602
- `
28083
+ print(
28084
+ snapshots.map(
28085
+ ({ source: item, snapshot }) => renderDetailedStatus(terminal, item, snapshot)
28086
+ ).join("\n\n")
27603
28087
  );
27604
28088
  }
27605
28089
  var ROLLBACK_NOTICE_MS = 7 * 24 * 60 * 60 * 1e3;
@@ -27609,7 +28093,7 @@ async function runtimeSummaryText() {
27609
28093
  if (state === null) return null;
27610
28094
  const settings = await readRuntimeSettings(paths);
27611
28095
  const rejected = state.rejected.at(-1);
27612
- return renderRuntime({
28096
+ return renderRuntime(terminal, {
27613
28097
  version: state.current,
27614
28098
  autoUpdate: settings.autoUpdate,
27615
28099
  confirming: state.trial?.version ?? null,
@@ -27667,10 +28151,15 @@ async function waitForTrial(to) {
27667
28151
  `Version ${to} did not start and Iteration returned to ${state.current}. ${rejected?.reason ?? ""}`.trim()
27668
28152
  );
27669
28153
  }
27670
- if (state?.trial === null) return `Iteration is updated to ${to}.`;
28154
+ if (state?.trial === null)
28155
+ return mark(terminal, "success", `Iteration is updated to ${to}`);
27671
28156
  await new Promise((resolve) => setTimeout(resolve, 1e3));
27672
28157
  }
27673
- return `Iteration is updated to ${to}; collectors are still starting. Run iteration to check.`;
28158
+ return mark(
28159
+ terminal,
28160
+ "warning",
28161
+ `Iteration is updated to ${to}; collectors are still starting. Run ${terminal.bold("iteration")} to check.`
28162
+ );
27674
28163
  }
27675
28164
  async function update(setting, values) {
27676
28165
  requireCollectorPlatform();
@@ -27687,8 +28176,16 @@ async function update(setting, values) {
27687
28176
  ...setting === void 0 ? {} : { autoUpdate: setting === "on" },
27688
28177
  ...registry3 === null ? {} : { registry: validateRegistryUrl(registry3).toString() }
27689
28178
  });
27690
- process.stdout.write(
27691
- setting === "off" ? "Automatic updates are off. Run iteration update to update.\n" : setting === "on" ? "Automatic updates are on.\n" : "The update registry is saved.\n"
28179
+ print(
28180
+ setting === "off" ? mark(
28181
+ terminal,
28182
+ "success",
28183
+ `Automatic updates are off. Run ${terminal.bold("iteration update")} to update.`
28184
+ ) : mark(
28185
+ terminal,
28186
+ "success",
28187
+ setting === "on" ? "Automatic updates are on" : "The update registry is saved"
28188
+ )
27692
28189
  );
27693
28190
  return;
27694
28191
  }
@@ -27698,33 +28195,56 @@ async function update(setting, values) {
27698
28195
  throw new Error(
27699
28196
  "No collector is set up on this computer. Run iteration connect first."
27700
28197
  );
28198
+ const stopChecking = startSpinner(
28199
+ process.stdout,
28200
+ terminal,
28201
+ "Checking for updates\u2026"
28202
+ );
27701
28203
  const outcome = await updateRuntime(paths, {
27702
28204
  manual: true,
27703
28205
  expected,
27704
28206
  nowMs: Date.now(),
27705
28207
  signal: AbortSignal.timeout(6e5)
27706
- });
28208
+ }).finally(stopChecking);
27707
28209
  if (outcome.kind === "busy") {
27708
- process.stdout.write(
27709
- "Another update is in progress. Run iteration to check.\n"
28210
+ print(
28211
+ mark(
28212
+ terminal,
28213
+ "warning",
28214
+ `Another update is in progress. Run ${terminal.bold("iteration")} to check.`
28215
+ )
27710
28216
  );
27711
28217
  return;
27712
28218
  }
27713
28219
  if (outcome.kind === "up_to_date") {
27714
- process.stdout.write(
27715
- `Iteration ${outcome.version} is the latest version.
27716
- `
28220
+ print(
28221
+ mark(
28222
+ terminal,
28223
+ "success",
28224
+ `Iteration ${outcome.version} is the latest version`
28225
+ )
27717
28226
  );
27718
28227
  return;
27719
28228
  }
27720
28229
  if (outcome.kind === "waiting") {
27721
- process.stdout.write(`No update was installed: ${outcome.reason}.
27722
- `);
28230
+ print(
28231
+ mark(terminal, "warning", `No update was installed: ${outcome.reason}.`)
28232
+ );
27723
28233
  return;
27724
28234
  }
27725
- await refreshBackgroundServices(true);
27726
- process.stdout.write(`${await waitForTrial(outcome.to)}
27727
- `);
28235
+ const stopStarting = startSpinner(
28236
+ process.stdout,
28237
+ terminal,
28238
+ `Starting Iteration ${outcome.to}\u2026`
28239
+ );
28240
+ let result;
28241
+ try {
28242
+ await refreshBackgroundServices(true);
28243
+ result = await waitForTrial(outcome.to);
28244
+ } finally {
28245
+ stopStarting();
28246
+ }
28247
+ print(result);
27728
28248
  }
27729
28249
  async function runInternalCommand() {
27730
28250
  if (process.argv[2] === "supervise") {
@@ -27757,7 +28277,14 @@ async function runInternalCommand() {
27757
28277
  }
27758
28278
  return false;
27759
28279
  }
28280
+ var BACKGROUND_COMMANDS = /* @__PURE__ */ new Set([
28281
+ "run",
28282
+ "supervise",
28283
+ "claude-git-hook",
28284
+ "turn-summary-hook"
28285
+ ]);
27760
28286
  async function main() {
28287
+ if (!BACKGROUND_COMMANDS.has(process.argv[2] ?? "")) silenceCollectorLogs();
27761
28288
  if (await runInternalCommand()) return;
27762
28289
  const delegated = await delegateToInstalledVersion();
27763
28290
  if (delegated !== null) {
@@ -27805,8 +28332,22 @@ async function signOut(source, values) {
27805
28332
  "Run iteration logout without a source. Only --data-directory is supported."
27806
28333
  );
27807
28334
  await logout(optionalString(values, "data-directory") ?? void 0);
27808
- process.stdout.write(
27809
- "Signed out of Iteration on this computer. Collection stopped and saved credentials removed.\nLocal pending data was archived. Agent sessions and uploaded data were kept.\nRun iteration connect to sign in again.\n"
28335
+ print(
28336
+ mark(
28337
+ terminal,
28338
+ "success",
28339
+ terminal.bold("Signed out of Iteration on this computer")
28340
+ ),
28341
+ "",
28342
+ wrap(
28343
+ terminal,
28344
+ "Collection stopped and saved credentials were removed. Local pending data was archived. Agent sessions and uploaded data were kept."
28345
+ ),
28346
+ "",
28347
+ wrap(
28348
+ terminal,
28349
+ `Run ${terminal.bold("iteration connect")} to sign in again.`
28350
+ )
27810
28351
  );
27811
28352
  }
27812
28353
  async function showHome(values) {
@@ -27818,9 +28359,7 @@ async function showHome(values) {
27818
28359
  if (isCollectorPlatform()) await adoptRuntime();
27819
28360
  await defaultCommand();
27820
28361
  const summary = await runtimeSummaryText();
27821
- if (summary !== null) process.stdout.write(`
27822
- ${summary}
27823
- `);
28362
+ if (summary !== null) print("", summary);
27824
28363
  }
27825
28364
  async function disconnect(selectedSource, values) {
27826
28365
  await uninstallBackgroundService(selectedSource);
@@ -27831,8 +28370,13 @@ async function disconnect(selectedSource, values) {
27831
28370
  await uninstallCursorHooks(config3.cursorHome, config3.dataDirectory);
27832
28371
  else await uninstallTurnSummary(config3);
27833
28372
  }
27834
- process.stdout.write(
27835
- "Collector startup removed. Local pending data was retained.\n"
28373
+ print(
28374
+ mark(
28375
+ terminal,
28376
+ "success",
28377
+ `${collectorSourceLabel(selectedSource)} is disconnected`
28378
+ ),
28379
+ wrap(terminal, "Collection stopped. Local pending data was kept.")
27836
28380
  );
27837
28381
  }
27838
28382
  async function dispatchSourceCommand(command, source, values, selectedSource) {
@@ -27847,7 +28391,9 @@ async function dispatchSourceCommand(command, source, values, selectedSource) {
27847
28391
  };
27848
28392
  validateSourceOptions();
27849
28393
  if (command === "connect" && selectedSource !== null) {
27850
- await initialize(selectedSource, values);
28394
+ print(brand(terminal), "");
28395
+ const { result } = await initialize(selectedSource, values);
28396
+ print(...connectionSummary2([result], true));
27851
28397
  return;
27852
28398
  }
27853
28399
  if (command === "run") {
@@ -27879,9 +28425,7 @@ async function showStatus(source, selectedSource, values) {
27879
28425
  await adoptRuntime();
27880
28426
  await status(selectedSource ?? void 0, values);
27881
28427
  const summary = await runtimeSummaryText();
27882
- if (summary !== null) process.stdout.write(`
27883
- ${summary}
27884
- `);
28428
+ if (summary !== null) print("", summary);
27885
28429
  }
27886
28430
  var background = process.argv[2] === "run";
27887
28431
  main().then(
@@ -27889,8 +28433,9 @@ main().then(
27889
28433
  if (background) process.exit(process.exitCode ?? 0);
27890
28434
  },
27891
28435
  (error3) => {
28436
+ const message = error3 instanceof Error ? error3.message : "Unknown Iteration CLI error.";
27892
28437
  process.stderr.write(
27893
- `${error3 instanceof Error ? error3.message : "Unknown Iteration CLI error."}
28438
+ `${process.stderr.isTTY ? mark(terminalFor(process.stderr), "failure", message) : message}
27894
28439
  `
27895
28440
  );
27896
28441
  process.exitCode = 1;