@mnemonik/cli 7.140.3 → 7.141.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.
Files changed (40) hide show
  1. package/dist/auth/credentials.js +266 -3
  2. package/dist/auth/index.js +266 -3
  3. package/dist/auth/installSession.js +262 -0
  4. package/dist/auth/status.js +262 -0
  5. package/dist/authorizationWords.js +262 -0
  6. package/dist/diagnostics.js +266 -3
  7. package/dist/digests.json +38 -38
  8. package/dist/hooksLog.js +4 -0
  9. package/dist/identity/migrate.js +266 -3
  10. package/dist/install/hosts.js +262 -0
  11. package/dist/install/journal.js +266 -3
  12. package/dist/install/journey.js +266 -3
  13. package/dist/install/ownership.js +266 -3
  14. package/dist/install/transaction.js +266 -3
  15. package/dist/install/ui.js +266 -3
  16. package/dist/installSession.js +262 -0
  17. package/dist/installation.js +266 -3
  18. package/dist/launcher.js +266 -3
  19. package/dist/preflight.js +354 -92
  20. package/dist/project/eligibility.js +266 -3
  21. package/dist/project/records.js +266 -3
  22. package/dist/project.js +270 -7
  23. package/dist/router.js +270 -7
  24. package/dist/runtime/releaseSource.js +266 -3
  25. package/dist/runtime/selfUpdate.js +266 -3
  26. package/dist/runtime/signers.js +67 -7
  27. package/dist/runtime/store.js +4 -0
  28. package/dist/runtime/updateCheck.js +266 -3
  29. package/dist/sbom.json +21 -21
  30. package/dist/scanner/control.js +266 -3
  31. package/dist/scanner/data.js +262 -0
  32. package/dist/scanner/discover.js +354 -92
  33. package/dist/scanner/enable.js +270 -7
  34. package/dist/scanner/picker.js +325 -63
  35. package/dist/scanner/service.js +266 -3
  36. package/dist/scanner/update.js +266 -3
  37. package/dist/scanner-release.json +24 -24
  38. package/dist/status.js +266 -3
  39. package/dist/vendor/local-setup.js +266 -3
  40. package/package.json +31 -31
@@ -915,69 +915,6 @@ var MCP_INSTRUCTIONS = getMcpInstructions();
915
915
  // packages/shared/dist/codeScanner.js
916
916
  var import_ignore = __toESM(require_ignore(), 1);
917
917
 
918
- // packages/shared/dist/protectedPaths.js
919
- import { homedir } from "node:os";
920
- import { posix, win32 } from "node:path";
921
- function pathsFor(platform) {
922
- return platform === "win32" ? win32 : posix;
923
- }
924
- function mnemonikStateDirectory(platform = process.platform, env = process.env, home = homedir()) {
925
- if (env.MNEMONIK_STATE_DIR)
926
- return env.MNEMONIK_STATE_DIR;
927
- if (platform === "win32")
928
- return win32.join(env.LOCALAPPDATA || win32.join(home, "AppData", "Local"), "Mnemonik");
929
- if (platform === "darwin")
930
- return posix.join(home, "Library", "Application Support", "Mnemonik");
931
- return posix.join(env.XDG_STATE_HOME || posix.join(home, ".local", "state"), "mnemonik");
932
- }
933
- function protectedLocalPaths(platform = process.platform, env = process.env, home = homedir()) {
934
- const path = pathsFor(platform);
935
- const localAppData = env.LOCALAPPDATA || win32.join(home, "AppData", "Local");
936
- const appData = env.APPDATA || win32.join(home, "AppData", "Roaming");
937
- const state = mnemonikStateDirectory(platform, env, home);
938
- const common = [
939
- state,
940
- path.join(home, ".mnemonik"),
941
- path.join(home, ".claude", ".credentials.json"),
942
- path.join(home, ".codex", "auth.json"),
943
- path.join(home, ".cursor", "mcp.json"),
944
- path.join(home, ".grok", "mcp_credentials.json")
945
- ];
946
- const osPaths = platform === "darwin" ? [path.join(home, "Library", "Keychains")] : platform === "win32" ? [
947
- win32.join(appData, "Microsoft", "Credentials"),
948
- win32.join(localAppData, "Microsoft", "Credentials"),
949
- win32.join(appData, "Microsoft", "Protect")
950
- ] : [
951
- path.join(home, ".local", "share", "keyrings"),
952
- path.join(home, ".gnupg"),
953
- path.join(home, ".ssh"),
954
- path.join(home, ".aws"),
955
- path.join(home, ".config", "gcloud"),
956
- path.join(home, ".docker", "config.json"),
957
- path.join(home, ".npmrc"),
958
- path.join(home, ".netrc"),
959
- path.join(home, ".pypirc")
960
- ];
961
- return [.../* @__PURE__ */ new Set([...common, ...osPaths])];
962
- }
963
- function comparable(value, platform) {
964
- const path = pathsFor(platform);
965
- const normalized = path.resolve(value);
966
- return platform === "win32" || platform === "darwin" ? normalized.toLowerCase() : normalized;
967
- }
968
- function isProtectedLocalPath(candidate, protectedPaths = protectedLocalPaths(), platform = process.platform) {
969
- const path = pathsFor(platform);
970
- const target = comparable(candidate, platform);
971
- return protectedPaths.some((protectedPath) => {
972
- const parent = comparable(protectedPath, platform);
973
- const relative = path.relative(parent, target);
974
- return relative === "" || !relative.startsWith(`..${path.sep}`) && relative !== ".." && !path.isAbsolute(relative);
975
- });
976
- }
977
- function protectedPathsWithinRoot(root, protectedPaths = protectedLocalPaths(), platform = process.platform) {
978
- return protectedPaths.filter((candidate) => isProtectedLocalPath(candidate, [root], platform));
979
- }
980
-
981
918
  // node_modules/web-tree-sitter/web-tree-sitter.js
982
919
  var __defProp2 = Object.defineProperty;
983
920
  var __name = (target, value) => __defProp2(target, "name", { value, configurable: true });
@@ -5029,6 +4966,331 @@ var WASM_DIR = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "wasm")
5029
4966
  // packages/shared/dist/ast/astChunker.js
5030
4967
  var MAX_AST_PARSE_BYTES = 2 * 1024 * 1024;
5031
4968
 
4969
+ // packages/shared/dist/redactCredentials.js
4970
+ var REDACTED = "<redacted credential>";
4971
+ var MAX_PEM_BODY_LENGTH = 8 * 1024;
4972
+ var LETTER_OR_DIGIT = /[A-Za-z0-9]/;
4973
+ function hasLetterOrDigit(value) {
4974
+ return LETTER_OR_DIGIT.test(value);
4975
+ }
4976
+ function redactContextValue(match, head = "", value = "") {
4977
+ return hasLetterOrDigit(value) ? `${head}${REDACTED}` : match;
4978
+ }
4979
+ var PLACEHOLDER_PASSWORD = /^(?:\[REDACTED(?::[A-Za-z0-9_-]+)?\]|redacted|<[^<>]*>|\{\{[^{}]*\}\}|\$\{[^{}]+\}|%[A-Za-z_][A-Za-z0-9_]*%|\*+|x{3,}|\.\.\.|\u2026|password|passwd|pass|pwd|pw|secret|changeme|change[_-]me|example|test|(?:your|my)[a-z_-]*?(?:password|passwd|pass|pwd|secret|key|token|here))$/i;
4980
+ var PLACEHOLDER_ENV_VAR = /^\$[A-Z_][A-Z0-9_]*$/;
4981
+ function isPlaceholderPassword(password) {
4982
+ return PLACEHOLDER_PASSWORD.test(password) || PLACEHOLDER_ENV_VAR.test(password);
4983
+ }
4984
+ function redactUrlPassword(match, head = "", password = "") {
4985
+ return isPlaceholderPassword(password) || !hasLetterOrDigit(password) ? match : `${head}${REDACTED}@`;
4986
+ }
4987
+ var SHELL_WORD = String.raw`'[^'\n]*'|"[^"\n]*"|(?!${REDACTED})[^\s'"\`;|&()[\]{}\\,/][^\s'"\`;|&]*`;
4988
+ var OPENING_QUOTE = String.raw`(["'\`]?)`;
4989
+ var TRAILING_PUNCTUATION = /[.,:;!?)\]}]+$/;
4990
+ var PROSE_WORDS = /* @__PURE__ */ new Set([
4991
+ "a",
4992
+ "an",
4993
+ "and",
4994
+ "as",
4995
+ "for",
4996
+ "in",
4997
+ "is",
4998
+ "it",
4999
+ "on",
5000
+ "or",
5001
+ "the",
5002
+ "to",
5003
+ "with",
5004
+ "flag",
5005
+ "option",
5006
+ "argument",
5007
+ "instead",
5008
+ "which",
5009
+ "that",
5010
+ "this",
5011
+ "puts",
5012
+ "passes",
5013
+ "leaks",
5014
+ "exposes"
5015
+ ]);
5016
+ var REGEX_DELIMITER = /\/(?:[{}()[\];]|$)/;
5017
+ function shellWordSecret(word) {
5018
+ const quote = word[0];
5019
+ if ((quote === "'" || quote === '"') && word.length >= 2 && word.endsWith(quote)) {
5020
+ const inner = word.slice(1, -1);
5021
+ if (!hasLetterOrDigit(inner) || quote === '"' && inner.startsWith("$"))
5022
+ return null;
5023
+ if (inner !== inner.trim())
5024
+ return null;
5025
+ return isPlaceholderPassword(inner) ? null : inner;
5026
+ }
5027
+ if (word.startsWith("$"))
5028
+ return null;
5029
+ const core = word.replace(TRAILING_PUNCTUATION, "");
5030
+ if (!hasLetterOrDigit(core) || isPlaceholderPassword(core))
5031
+ return null;
5032
+ if (REGEX_DELIMITER.test(core))
5033
+ return null;
5034
+ return PROSE_WORDS.has(core.toLowerCase()) ? null : core;
5035
+ }
5036
+ function redactShellWord(match, head = "", word = "", tail = "") {
5037
+ return shellWordSecret(word) === null ? match : `${head}${REDACTED}${tail}`;
5038
+ }
5039
+ function redactQuotedShellWord(match, head = "", openingQuote = "", word = "", tail = "") {
5040
+ if (openingQuote !== "" && word.startsWith(openingQuote))
5041
+ return match;
5042
+ return redactShellWord(match, head, word, tail);
5043
+ }
5044
+ var SSHPASS_COMMAND = String.raw`ssh|scp|sftp|rsync|ssh-copy-id|ansible[\w-]*`;
5045
+ function redactSshpassWord(match, head = "", openingQuote = "", word = "", tail = "", command = "") {
5046
+ if (openingQuote !== "" && word.startsWith(openingQuote))
5047
+ return match;
5048
+ const secret = shellWordSecret(word);
5049
+ if (secret === null)
5050
+ return match;
5051
+ const bare = word[0] !== "'" && word[0] !== '"';
5052
+ if (bare && /^[a-z]+$/.test(secret) && command === "")
5053
+ return match;
5054
+ return `${head}${REDACTED}${tail}`;
5055
+ }
5056
+ var PATTERNS = [
5057
+ {
5058
+ kind: "bearer",
5059
+ pattern: /(\bBearer\s+)([^\s]{40,})/gi,
5060
+ replacement: redactContextValue,
5061
+ secretGroup: 2
5062
+ },
5063
+ {
5064
+ // Before openai, whose sk- shape would otherwise claim these keys.
5065
+ kind: "anthropic",
5066
+ pattern: /(?<![A-Za-z0-9_-])sk-ant-(?=[_-]*[A-Za-z0-9])[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g,
5067
+ replacement: REDACTED
5068
+ },
5069
+ {
5070
+ kind: "openai",
5071
+ pattern: /(?<![A-Za-z0-9_-])sk-(?:proj-)?(?=[_-]*[A-Za-z0-9])[A-Za-z0-9_-]{16,}(?![A-Za-z0-9_-])/g,
5072
+ replacement: REDACTED
5073
+ },
5074
+ {
5075
+ kind: "shopify",
5076
+ pattern: /(?<![A-Za-z0-9_])shp(?:at|ss|ca)_[A-Za-z0-9]{16,}(?![A-Za-z0-9])/g,
5077
+ replacement: REDACTED
5078
+ },
5079
+ {
5080
+ kind: "aws_access_key",
5081
+ pattern: /(?<![A-Z0-9])AKIA[A-Z0-9]{16}(?![A-Z0-9])/g,
5082
+ replacement: REDACTED
5083
+ },
5084
+ {
5085
+ kind: "github",
5086
+ pattern: /(?<![A-Za-z0-9_])gh[opu]_[A-Za-z0-9]{20,}(?![A-Za-z0-9])/g,
5087
+ replacement: REDACTED
5088
+ },
5089
+ {
5090
+ kind: "slack",
5091
+ pattern: /(?<![A-Za-z0-9-])xox[abp]-(?=-*[A-Za-z0-9])[A-Za-z0-9-]{10,}(?![A-Za-z0-9-])/g,
5092
+ replacement: REDACTED
5093
+ },
5094
+ {
5095
+ kind: "sentry",
5096
+ pattern: /(?<![A-Za-z0-9_])sntry[us]_(?=[_-]*[A-Za-z0-9])[A-Za-z0-9_-]{16,}(?![A-Za-z0-9_-])/g,
5097
+ replacement: REDACTED
5098
+ },
5099
+ {
5100
+ kind: "fly",
5101
+ pattern: /(?<![A-Za-z0-9_])(?:FlyV1\s+)?fm2_(?=[_-]*[A-Za-z0-9])[A-Za-z0-9_-]{16,}(?![A-Za-z0-9_-])/g,
5102
+ replacement: REDACTED
5103
+ },
5104
+ {
5105
+ kind: "google_api_key",
5106
+ pattern: /(?<![A-Za-z0-9_-])AIza(?=[_-]*[A-Za-z0-9])[0-9A-Za-z_-]{35}(?![A-Za-z0-9_-])/g,
5107
+ replacement: REDACTED
5108
+ },
5109
+ {
5110
+ kind: "jwt",
5111
+ // header.payload.signature, both JSON segments starting eyJ. The length
5112
+ // floors keep `eyJ...` prose and signature-less examples out.
5113
+ pattern: /(?<![A-Za-z0-9_-])eyJ[A-Za-z0-9_-]{8,}\.eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{16,}(?![A-Za-z0-9_-])/g,
5114
+ replacement: REDACTED
5115
+ },
5116
+ {
5117
+ kind: "mnemonik_component_token",
5118
+ // mnc_ / mncr_ + 43 base64url (oauth/components.ts); 32+ also catches a
5119
+ // partial token. The body must contain an upper-case letter or digit, so a
5120
+ // snake_case identifier is not mistaken for one; the 8-character
5121
+ // display prefix (mnc_ + 8) is too short.
5122
+ pattern: /(?<![A-Za-z0-9_])mncr?_(?=[A-Za-z0-9_-]*[A-Z0-9])[A-Za-z0-9_-]{32,}/g,
5123
+ replacement: REDACTED
5124
+ },
5125
+ {
5126
+ kind: "stripe",
5127
+ // Secret and restricted keys (sk_/rk_ live|test) and webhook signing secrets.
5128
+ pattern: /(?<![A-Za-z0-9_])(?:(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}|whsec_[A-Za-z0-9]{20,})(?![A-Za-z0-9])/g,
5129
+ replacement: REDACTED
5130
+ },
5131
+ {
5132
+ kind: "mnemonik_proxy_token",
5133
+ // pxt_ + 32 hex (the format server.ts validates). A bare prefix in prose is left.
5134
+ pattern: /(?<![A-Za-z0-9_])pxt_[0-9a-f]{32,}/g,
5135
+ replacement: REDACTED
5136
+ },
5137
+ {
5138
+ kind: "mnemonik_api_key",
5139
+ // mnk_ + 64 hex (AuthManager.generateApiKey); 32+ also catches a half key.
5140
+ // The stored 12-character key_prefix (mnk_ + 8 hex) is not a credential.
5141
+ pattern: /(?<![A-Za-z0-9_])mnk_[0-9a-f]{32,}/g,
5142
+ replacement: REDACTED
5143
+ },
5144
+ {
5145
+ kind: "mnemonik_api_key_legacy",
5146
+ // mnk_ + 43 base64url: keys minted by hand before AuthManager's hex form
5147
+ // (production's only key in 2026-10 has this shape, and one stored memory
5148
+ // held a development key in it). Authentication accepts any mnk_ bearer.
5149
+ // The body needs upper and lower case and a digit, so a snake_case
5150
+ // identifier that starts mnk_ is not taken for one.
5151
+ pattern: /(?<![A-Za-z0-9_])mnk_(?=[A-Za-z0-9_-]*[A-Z])(?=[A-Za-z0-9_-]*[a-z])(?=[A-Za-z0-9_-]*[0-9])[A-Za-z0-9_-]{40,}(?![A-Za-z0-9_-])/g,
5152
+ replacement: REDACTED
5153
+ },
5154
+ {
5155
+ kind: "named_value",
5156
+ pattern: /(\b[A-Za-z_][A-Za-z0-9_]*(?:_TOKEN|_KEY|_SECRET|_PASSWORD|_PASS|APIKEY|API_KEY)\s*(?:=|:)\s*)([^\s]{16,})/gi,
5157
+ replacement: redactContextValue,
5158
+ secretGroup: 2
5159
+ },
5160
+ {
5161
+ kind: "connection_string",
5162
+ // scheme://user:password@host: only the password is replaced; scheme,
5163
+ // user, host and database stay readable. The user may be empty
5164
+ // (redis://:password@host). The password runs to the last `@` before a
5165
+ // path, query, fragment, quote or whitespace, so an unencoded `@` inside
5166
+ // it is still covered. Runs after named_value, which already replaces a
5167
+ // whole URL assigned to a secret-named variable.
5168
+ pattern: /\b((?:postgres(?:ql)?|mysql|mariadb|mongodb|rediss?|amqps?|mssql|sqlserver)(?:\+[a-z0-9]+)?:\/\/[^\s:/?#@'"`<>]{0,256}:)([^\s/?#'"`]{1,512})@/gi,
5169
+ replacement: redactUrlPassword,
5170
+ secretGroup: 2
5171
+ },
5172
+ {
5173
+ kind: "url_basic_auth",
5174
+ // https://user:password@host: same shape and placeholder rules as a
5175
+ // connection string; only the password is replaced.
5176
+ pattern: /\b(https?:\/\/[^\s:/?#@'"`<>]{0,256}:)([^\s/?#'"`]{1,512})@/gi,
5177
+ replacement: redactUrlPassword,
5178
+ secretGroup: 2
5179
+ },
5180
+ // Command-line passwords. Each keeps the command and replaces only the
5181
+ // password word; an expansion or placeholder in that position is left.
5182
+ {
5183
+ // sshpass -p <password> (also -p'<password>' and -p"<password>"), after
5184
+ // any other sshpass flags. 13 memories, 11 scanner chunks, 15 versions and
5185
+ // 6 dated facts in production held one on 2026-10-12.
5186
+ kind: "sshpass_password",
5187
+ pattern: new RegExp(String.raw`(${OPENING_QUOTE}\bsshpass(?:[ \t]+-[a-oq-zA-Z]\S*)*[ \t]+-p[ \t]*)(${SHELL_WORD})()(?=((?:[ \t]+(?:${SSHPASS_COMMAND})(?![\w-]))?))`, "g"),
5188
+ replacement: redactSshpassWord,
5189
+ secretGroup: 3,
5190
+ commandLine: true
5191
+ },
5192
+ {
5193
+ // Environment variables whose only purpose is a password, in shell
5194
+ // assignment form (no space around `=`): libpq's PGPASSWORD (one memory,
5195
+ // version and fact in production), MySQL's MYSQL_PWD, sshpass -e's
5196
+ // SSHPASS. named_value needs an `_PASSWORD`-style suffix and 16
5197
+ // characters, so it misses all three. Not an awk program that matches or
5198
+ // prints the assignment: `/^PGPASSWORD=/ { print "PGPASSWORD=" pw }`.
5199
+ kind: "password_env_var",
5200
+ pattern: new RegExp(String.raw`(${OPENING_QUOTE}\b(?:PGPASSWORD|MYSQL_PWD|SSHPASS)=)(${SHELL_WORD})()`, "g"),
5201
+ replacement: redactQuotedShellWord,
5202
+ secretGroup: 3,
5203
+ commandLine: true
5204
+ },
5205
+ {
5206
+ // --password=<value>, the long option every CLI that takes one spells
5207
+ // this way. The `=` keeps prose about the option ("--password is
5208
+ // required") out; the spaced form is not matched for that reason.
5209
+ kind: "password_option",
5210
+ pattern: new RegExp(String.raw`(${OPENING_QUOTE}(?<![\w-])--password=)(${SHELL_WORD})()`, "g"),
5211
+ replacement: redactQuotedShellWord,
5212
+ secretGroup: 3,
5213
+ commandLine: true
5214
+ },
5215
+ {
5216
+ // echo <password> | sudo -S: sudo reads the password from stdin. One
5217
+ // memory, two versions and two facts in production.
5218
+ kind: "sudo_password",
5219
+ pattern: new RegExp(String.raw`(\becho[ \t]+(?:-[neE]+[ \t]+)?)(${SHELL_WORD})([ \t]*\|[ \t]*sudo\b[^|\n]*?[ \t](?:-[A-Za-z]*S[A-Za-z]*|--stdin)\b)`, "g"),
5220
+ replacement: redactShellWord,
5221
+ secretGroup: 2,
5222
+ commandLine: true
5223
+ }
5224
+ ];
5225
+
5226
+ // packages/shared/dist/secretPatterns.js
5227
+ var SECRET_LABEL = String.raw`[\w$-]*(?:api[_-]?key|secret|token|password|credential|auth)|aws_secret_access_key`;
5228
+ var SECRET_LABEL_RE = new RegExp(`^(?:${SECRET_LABEL}|MYSQL_PWD|SSHPASS)$`, "i");
5229
+ var LABELED_VALUE_RE = new RegExp(String.raw`(?<![\w$-])((["']?)(?:${SECRET_LABEL})\2\s*[:=]\s*)(?=\S)`, "gi");
5230
+
5231
+ // packages/shared/dist/protectedPaths.js
5232
+ import { homedir } from "node:os";
5233
+ import { posix, win32 } from "node:path";
5234
+ function pathsFor(platform) {
5235
+ return platform === "win32" ? win32 : posix;
5236
+ }
5237
+ function mnemonikStateDirectory(platform = process.platform, env = process.env, home = homedir()) {
5238
+ if (env.MNEMONIK_STATE_DIR)
5239
+ return env.MNEMONIK_STATE_DIR;
5240
+ if (platform === "win32")
5241
+ return win32.join(env.LOCALAPPDATA || win32.join(home, "AppData", "Local"), "Mnemonik");
5242
+ if (platform === "darwin")
5243
+ return posix.join(home, "Library", "Application Support", "Mnemonik");
5244
+ return posix.join(env.XDG_STATE_HOME || posix.join(home, ".local", "state"), "mnemonik");
5245
+ }
5246
+ function protectedLocalPaths(platform = process.platform, env = process.env, home = homedir()) {
5247
+ const path = pathsFor(platform);
5248
+ const localAppData = env.LOCALAPPDATA || win32.join(home, "AppData", "Local");
5249
+ const appData = env.APPDATA || win32.join(home, "AppData", "Roaming");
5250
+ const state = mnemonikStateDirectory(platform, env, home);
5251
+ const common = [
5252
+ state,
5253
+ path.join(home, ".mnemonik"),
5254
+ path.join(home, ".claude", ".credentials.json"),
5255
+ path.join(home, ".codex", "auth.json"),
5256
+ path.join(home, ".cursor", "mcp.json"),
5257
+ path.join(home, ".grok", "mcp_credentials.json")
5258
+ ];
5259
+ const osPaths = platform === "darwin" ? [path.join(home, "Library", "Keychains")] : platform === "win32" ? [
5260
+ win32.join(appData, "Microsoft", "Credentials"),
5261
+ win32.join(localAppData, "Microsoft", "Credentials"),
5262
+ win32.join(appData, "Microsoft", "Protect")
5263
+ ] : [
5264
+ path.join(home, ".local", "share", "keyrings"),
5265
+ path.join(home, ".gnupg"),
5266
+ path.join(home, ".ssh"),
5267
+ path.join(home, ".aws"),
5268
+ path.join(home, ".config", "gcloud"),
5269
+ path.join(home, ".docker", "config.json"),
5270
+ path.join(home, ".npmrc"),
5271
+ path.join(home, ".netrc"),
5272
+ path.join(home, ".pypirc")
5273
+ ];
5274
+ return [.../* @__PURE__ */ new Set([...common, ...osPaths])];
5275
+ }
5276
+ function comparable(value, platform) {
5277
+ const path = pathsFor(platform);
5278
+ const normalized = path.resolve(value);
5279
+ return platform === "win32" || platform === "darwin" ? normalized.toLowerCase() : normalized;
5280
+ }
5281
+ function isProtectedLocalPath(candidate, protectedPaths = protectedLocalPaths(), platform = process.platform) {
5282
+ const path = pathsFor(platform);
5283
+ const target = comparable(candidate, platform);
5284
+ return protectedPaths.some((protectedPath) => {
5285
+ const parent = comparable(protectedPath, platform);
5286
+ const relative = path.relative(parent, target);
5287
+ return relative === "" || !relative.startsWith(`..${path.sep}`) && relative !== ".." && !path.isAbsolute(relative);
5288
+ });
5289
+ }
5290
+ function protectedPathsWithinRoot(root, protectedPaths = protectedLocalPaths(), platform = process.platform) {
5291
+ return protectedPaths.filter((candidate) => isProtectedLocalPath(candidate, [root], platform));
5292
+ }
5293
+
5032
5294
  // packages/shared/dist/codeScanner.js
5033
5295
  var MAX_SCANNED_FILE_BYTES = 10 * 1024 * 1024;
5034
5296
  var BUILT_IN_IGNORE_DIRS = [