@sberpay-cli/cli-diagnostic 0.4.0-dev.5 → 0.4.0-dev.8

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.
@@ -27038,6 +27038,76 @@ function date4(params) {
27038
27038
  return _coercedDate(ZodDate, params);
27039
27039
  }
27040
27040
 
27041
+ // packages/cli/src/core/windowsAcl.ts
27042
+ import { spawnSync } from "node:child_process";
27043
+ import { dirname, win32 } from "node:path";
27044
+ var Sid = external_exports.string().regex(/^S-1-(?:\d+-)*\d+$/);
27045
+ var Inspection = external_exports.object({ owner: Sid, currentUser: Sid, reparse: external_exports.literal(false), rules: external_exports.array(external_exports.object({ sid: Sid, allow: external_exports.boolean(), rights: external_exports.number().int() })).min(1) });
27046
+ var WRITE_ACCESS = 852310 | 1342177280;
27047
+ function assertWindowsAcl(value, policy) {
27048
+ const parsed = Inspection.safeParse(value);
27049
+ if (!parsed.success) throw Error("WINDOWS_ACL_UNSAFE");
27050
+ const s = parsed.data, trusted = /* @__PURE__ */ new Set([s.currentUser, "S-1-5-18", "S-1-5-32-544"]);
27051
+ if (!trusted.has(s.owner) || s.rules.some((r) => r.allow && !trusted.has(r.sid) && (policy === "private" ? r.rights !== 0 : (r.rights & WRITE_ACCESS) !== 0))) throw Error("WINDOWS_ACL_UNSAFE");
27052
+ }
27053
+ var SCRIPT = String.raw`
27054
+ $ErrorActionPreference='Stop'
27055
+ [Console]::OutputEncoding=New-Object System.Text.UTF8Encoding($false)
27056
+ $p=[IO.Path]::GetFullPath($env:SBERPAY_ACL_PATH)
27057
+ $cursor=$p
27058
+ while($cursor){
27059
+ if(Test-Path -LiteralPath $cursor){
27060
+ $item=Get-Item -LiteralPath $cursor -Force
27061
+ if(($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0){throw 'REPARSE_POINT'}
27062
+ }
27063
+ $next=[IO.Path]::GetDirectoryName($cursor)
27064
+ if($next -eq $cursor){break};$cursor=$next
27065
+ }
27066
+ $sid=[Security.Principal.WindowsIdentity]::GetCurrent().User
27067
+ if($env:SBERPAY_ACL_ACTION -eq 'create' -and !(Test-Path -LiteralPath $p)){
27068
+ $acl=New-Object Security.AccessControl.DirectorySecurity
27069
+ $acl.SetOwner($sid);$acl.SetAccessRuleProtection($true,$false)
27070
+ foreach($id in @($sid.Value,'S-1-5-18','S-1-5-32-544')){
27071
+ $principal=New-Object Security.Principal.SecurityIdentifier($id)
27072
+ $rule=New-Object Security.AccessControl.FileSystemAccessRule($principal,'FullControl','ContainerInherit,ObjectInherit','None','Allow')
27073
+ $acl.AddAccessRule($rule)
27074
+ }
27075
+ [IO.Directory]::CreateDirectory($p,$acl)|Out-Null
27076
+ }
27077
+ $acl=Get-Acl -LiteralPath $p
27078
+ $rules=@($acl.GetAccessRules($true,$true,[Security.Principal.SecurityIdentifier])|ForEach-Object{
27079
+ @{sid=$_.IdentityReference.Value;allow=($_.AccessControlType -eq 'Allow');rights=[int]$_.FileSystemRights}
27080
+ })
27081
+ @{owner=$acl.GetOwner([Security.Principal.SecurityIdentifier]).Value;currentUser=$sid.Value;reparse=$false;rules=$rules}|ConvertTo-Json -Compress -Depth 5
27082
+ `;
27083
+ function windowsAclCommand(path, action, env = process.env) {
27084
+ const root = env.SystemRoot;
27085
+ if (!root || !win32.isAbsolute(root)) throw Error("WINDOWS_SYSTEM_ROOT_MISSING");
27086
+ return { file: win32.join(root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe"), args: ["-NoLogo", "-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(SCRIPT, "utf16le").toString("base64")], env: { SystemRoot: root, SBERPAY_ACL_PATH: path, SBERPAY_ACL_ACTION: action } };
27087
+ }
27088
+ function inspect(path, policy, action) {
27089
+ const c = windowsAclCommand(path, action);
27090
+ const r = spawnSync(c.file, c.args, { env: c.env, encoding: "utf8", windowsHide: true, timeout: 1e4, maxBuffer: 128 * 1024 });
27091
+ if (r.error || r.status !== 0) throw Error("WINDOWS_ACL_CHECK_FAILED");
27092
+ let value;
27093
+ try {
27094
+ value = JSON.parse(r.stdout.trim().replace(/^\uFEFF/, ""));
27095
+ } catch {
27096
+ throw Error("WINDOWS_ACL_CHECK_FAILED");
27097
+ }
27098
+ assertWindowsAcl(value, policy);
27099
+ }
27100
+ function assertWindowsPrivatePath(path) {
27101
+ inspect(path, "private", "inspect");
27102
+ }
27103
+ function ensureWindowsPrivateDirectory(path) {
27104
+ inspect(path, "private", "create");
27105
+ }
27106
+ function assertWindowsHelperPath(path) {
27107
+ inspect(path, "binary", "inspect");
27108
+ inspect(dirname(path), "binary", "inspect");
27109
+ }
27110
+
27041
27111
  // packages/cli/src/core/paths.ts
27042
27112
  import { homedir } from "node:os";
27043
27113
  import { join } from "node:path";
@@ -27278,7 +27348,7 @@ var active;
27278
27348
  var journalEvent = (kind2, data) => active?.event(kind2, data);
27279
27349
 
27280
27350
  // packages/cli/src/core/context.ts
27281
- import { appendFileSync, mkdirSync as mkdirSync5 } from "node:fs";
27351
+ import { appendFileSync, mkdirSync as mkdirSync5, existsSync as existsSync7 } from "node:fs";
27282
27352
  import { join as join6 } from "node:path";
27283
27353
 
27284
27354
  // packages/netlog/src/masking.ts
@@ -27454,15 +27524,18 @@ async function loggedFetch(logger, meta3, url2, init = {}) {
27454
27524
  }
27455
27525
 
27456
27526
  // packages/cli/src/core/config.ts
27457
- import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
27527
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
27458
27528
  import { join as join3 } from "node:path";
27459
27529
 
27460
27530
  // packages/cli/src/core/atomicFile.ts
27461
- import { mkdirSync, openSync, writeFileSync, fsyncSync, closeSync, renameSync, rmSync } from "node:fs";
27462
- import { dirname } from "node:path";
27531
+ import { mkdirSync, existsSync, openSync, writeFileSync, fsyncSync, closeSync, renameSync, rmSync } from "node:fs";
27532
+ import { dirname as dirname2 } from "node:path";
27463
27533
  import { randomUUID as randomUUID2 } from "node:crypto";
27464
27534
  function atomicJson(path, value) {
27465
- mkdirSync(dirname(path), { recursive: true, mode: 448 });
27535
+ if (process.platform === "win32") {
27536
+ ensureWindowsPrivateDirectory(dirname2(path));
27537
+ if (existsSync(path)) assertWindowsPrivatePath(path);
27538
+ } else mkdirSync(dirname2(path), { recursive: true, mode: 448 });
27466
27539
  const temp = `${path}.${randomUUID2()}.tmp`;
27467
27540
  try {
27468
27541
  const fd = openSync(temp, "wx", 384);
@@ -27474,7 +27547,7 @@ function atomicJson(path, value) {
27474
27547
  }
27475
27548
  renameSync(temp, path);
27476
27549
  if (process.platform !== "win32") {
27477
- const dir = openSync(dirname(path), "r");
27550
+ const dir = openSync(dirname2(path), "r");
27478
27551
  try {
27479
27552
  fsyncSync(dir);
27480
27553
  } finally {
@@ -27487,8 +27560,8 @@ function atomicJson(path, value) {
27487
27560
  }
27488
27561
 
27489
27562
  // packages/cli/src/core/fileLock.ts
27490
- import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, rmSync as rmSync2, renameSync as renameSync2, existsSync } from "node:fs";
27491
- import { dirname as dirname2, join as join2 } from "node:path";
27563
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, rmSync as rmSync2, renameSync as renameSync2, existsSync as existsSync2 } from "node:fs";
27564
+ import { dirname as dirname3, join as join2 } from "node:path";
27492
27565
  import { randomUUID as randomUUID3 } from "node:crypto";
27493
27566
 
27494
27567
  // packages/cli/src/core/output.ts
@@ -27610,7 +27683,7 @@ function owner(path) {
27610
27683
  }
27611
27684
  }
27612
27685
  async function withFileLock(path, fn, timeoutMs = 5e3) {
27613
- mkdirSync2(dirname2(path), { recursive: true, mode: 448 });
27686
+ mkdirSync2(dirname3(path), { recursive: true, mode: 448 });
27614
27687
  const nonce2 = randomUUID3(), deadline = Date.now() + timeoutMs;
27615
27688
  for (; ; ) {
27616
27689
  try {
@@ -27637,7 +27710,7 @@ async function withFileLock(path, fn, timeoutMs = 5e3) {
27637
27710
  } finally {
27638
27711
  if (acquired) rmSync2(reaper, { recursive: true, force: true });
27639
27712
  }
27640
- if (!existsSync(path)) continue;
27713
+ if (!existsSync2(path)) continue;
27641
27714
  }
27642
27715
  if (Date.now() >= deadline)
27643
27716
  throw new CliError(EXIT.CONFIG_OR_NETWORK, "BINDING_BUSY", "\u0414\u0440\u0443\u0433\u0430\u044F \u043A\u043E\u043C\u0430\u043D\u0434\u0430 \u0432\u043B\u0430\u0434\u0435\u0435\u0442 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0435\u043C \u0438\u043B\u0438 \u0432\u043B\u0430\u0434\u0435\u043B\u0435\u0446 \u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0438 \u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043D. \u041F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 \u043F\u043E\u0437\u0436\u0435.");
@@ -27656,7 +27729,7 @@ import { fileURLToPath } from "node:url";
27656
27729
  var NPM_PACKAGE = true ? "@sberpay-cli/cli-diagnostic" : "@sberpay-cli/cli";
27657
27730
  var kind = true ? "release" : "dev";
27658
27731
  var BUILD = {
27659
- sourceCommit: true ? "225bb38f8d48221f803cde8fcccc21a170308643" : "dev",
27732
+ sourceCommit: true ? "7f4bbd2ecf2ceb9eec2d043b2487863d9a74e578" : "dev",
27660
27733
  profile: true ? "diagnostic" : "standard",
27661
27734
  kind,
27662
27735
  // Бандл — dist/cli.mjs в корне пакета; этот файл под tsx — packages/cli/src/core/.
@@ -27719,8 +27792,9 @@ function isStand(value) {
27719
27792
  }
27720
27793
  function loadConfig(paths, build = BUILD) {
27721
27794
  const file2 = join3(paths.configDir, "config.json");
27722
- if (!existsSync2(file2)) return defaultConfig(build);
27795
+ if (!existsSync3(file2)) return defaultConfig(build);
27723
27796
  try {
27797
+ if (process.platform === "win32") assertWindowsPrivatePath(file2);
27724
27798
  return { ...defaultConfig(build), ...JSON.parse(readFileSync3(file2, "utf8")) };
27725
27799
  } catch (error62) {
27726
27800
  throw new CliError(
@@ -27847,7 +27921,7 @@ async function updateConfig(paths, transform3) {
27847
27921
  // packages/cli/src/core/secrets.ts
27848
27922
  import {
27849
27923
  chmodSync as chmodSync2,
27850
- existsSync as existsSync5,
27924
+ existsSync as existsSync6,
27851
27925
  mkdirSync as mkdirSync4,
27852
27926
  readFileSync as readFileSync5,
27853
27927
  renameSync as renameSync3,
@@ -28402,7 +28476,7 @@ function softwareDeviceKeys(storage, where = "os") {
28402
28476
  }
28403
28477
 
28404
28478
  // packages/device/src/helper.ts
28405
- import { spawn, spawnSync } from "node:child_process";
28479
+ import { spawn, spawnSync as spawnSync2 } from "node:child_process";
28406
28480
  var HELPER_PROTOCOL = 1;
28407
28481
  var TIMEOUT_MS = 15e3;
28408
28482
  var MAX_OUTPUT_BYTES = 64 * 1024;
@@ -28470,7 +28544,7 @@ async function callHelper(path, request, schema) {
28470
28544
  return parseReply(request.op, code, stdout, schema);
28471
28545
  }
28472
28546
  function callHelperSync(path, request, schema) {
28473
- const result = spawnSync(path, [], {
28547
+ const result = spawnSync2(path, [], {
28474
28548
  input: encode3(request),
28475
28549
  env: helperEnv(),
28476
28550
  stdio: ["pipe", "pipe", "ignore"],
@@ -28500,8 +28574,8 @@ function helperSecrets(helper) {
28500
28574
 
28501
28575
  // packages/device/src/hardware.ts
28502
28576
  import { createPublicKey as createPublicKey2, verify } from "node:crypto";
28503
- import { chmodSync, closeSync as closeSync2, existsSync as existsSync3, fsyncSync as fsyncSync2, linkSync, mkdirSync as mkdirSync3, openSync as openSync2, readFileSync as readFileSync4, rmSync as rmSync3, writeSync } from "node:fs";
28504
- import { dirname as dirname3 } from "node:path";
28577
+ import { chmodSync, closeSync as closeSync2, existsSync as existsSync4, fsyncSync as fsyncSync2, linkSync, mkdirSync as mkdirSync3, openSync as openSync2, readFileSync as readFileSync4, rmSync as rmSync3, writeSync } from "node:fs";
28578
+ import { dirname as dirname4 } from "node:path";
28505
28579
  var B64URL2 = external_exports.string().max(4096).regex(/^[A-Za-z0-9_-]+$/);
28506
28580
  var Point = external_exports.object({ x: B64URL2, y: B64URL2 });
28507
28581
  var Blobs = external_exports.object({ signKey: B64URL2, encKey: B64URL2 });
@@ -28517,7 +28591,7 @@ function toPublicKeys(pub) {
28517
28591
  return { deviceId: jwkThumbprint(publicKey), publicKey, encKey: jwk(pub.encPublicKey, "enc") };
28518
28592
  }
28519
28593
  function readBlobs(file2, kind2) {
28520
- if (!existsSync3(file2)) return void 0;
28594
+ if (!existsSync4(file2)) return void 0;
28521
28595
  const parsed = KeyFile.safeParse((() => {
28522
28596
  try {
28523
28597
  return JSON.parse(readFileSync4(file2, "utf8"));
@@ -28529,7 +28603,7 @@ function readBlobs(file2, kind2) {
28529
28603
  return { signKey: parsed.data.signKey, encKey: parsed.data.encKey };
28530
28604
  }
28531
28605
  function saveNewBlobs(file2, kind2, blobs) {
28532
- mkdirSync3(dirname3(file2), { recursive: true, mode: 448 });
28606
+ mkdirSync3(dirname4(file2), { recursive: true, mode: 448 });
28533
28607
  const tmp = `${file2}.${process.pid}.${Date.now()}.tmp`;
28534
28608
  const fd = openSync2(tmp, "wx", 384);
28535
28609
  try {
@@ -28562,7 +28636,7 @@ function checkSignature(pub, data, signature) {
28562
28636
  return signature;
28563
28637
  }
28564
28638
  async function hardwareAvailable(helper) {
28565
- if (!existsSync3(helper)) return false;
28639
+ if (!existsSync4(helper)) return false;
28566
28640
  try {
28567
28641
  return (await callHelper(helper, { op: "status" }, external_exports.object({ available: external_exports.boolean() }))).available;
28568
28642
  } catch {
@@ -28592,7 +28666,7 @@ function hardwareDeviceKeys({ kind: kind2, helper, file: file2 }) {
28592
28666
  return {
28593
28667
  kind: kind2,
28594
28668
  storage: "hardware",
28595
- exists: () => Boolean(blobs) || existsSync3(file2),
28669
+ exists: () => Boolean(blobs) || existsSync4(file2),
28596
28670
  ensure: publicKeys,
28597
28671
  async sign(data) {
28598
28672
  const signKey = required2().signKey;
@@ -28626,9 +28700,9 @@ function hardwareDeviceKeys({ kind: kind2, helper, file: file2 }) {
28626
28700
  }
28627
28701
 
28628
28702
  // packages/cli/src/core/keyHelper.ts
28629
- import { existsSync as existsSync4, realpathSync, statSync } from "node:fs";
28630
- import { dirname as dirname4, isAbsolute, join as join4 } from "node:path";
28631
- var PACKAGED = { "darwin-arm64": "darwin", "darwin-x64": "darwin", "linux-x64": "linux-x64", "linux-arm64": "linux-arm64" };
28703
+ import { existsSync as existsSync5, realpathSync, statSync } from "node:fs";
28704
+ import { dirname as dirname5, isAbsolute, join as join4 } from "node:path";
28705
+ var PACKAGED = { "darwin-arm64": "darwin", "darwin-x64": "darwin", "linux-x64": "linux-x64", "linux-arm64": "linux-arm64", "win32-x64": "win32-x64", "win32-arm64": "win32-arm64" };
28632
28706
  function chipOf(platform2) {
28633
28707
  if (platform2 === "darwin") return "secure-enclave";
28634
28708
  return platform2 === "linux" || platform2 === "win32" ? "tpm" : void 0;
@@ -28653,9 +28727,17 @@ function keyHelperFixHint(build = BUILD) {
28653
28727
  var WRITABLE_BY_GROUP = 16;
28654
28728
  var WRITABLE_BY_OTHERS = 2;
28655
28729
  function isTrustedFile(path) {
28730
+ if (process.platform === "win32") {
28731
+ try {
28732
+ assertWindowsHelperPath(path);
28733
+ return true;
28734
+ } catch {
28735
+ return false;
28736
+ }
28737
+ }
28656
28738
  const real = realpathSync(path);
28657
28739
  const uid = process.getuid?.() ?? 0;
28658
- return [real, dirname4(real)].every((p) => {
28740
+ return [real, dirname5(real)].every((p) => {
28659
28741
  const st = statSync(p);
28660
28742
  const groupOk = (st.mode & WRITABLE_BY_GROUP) === 0;
28661
28743
  return (st.uid === uid || st.uid === 0) && (st.mode & WRITABLE_BY_OTHERS) === 0 && groupOk;
@@ -28667,9 +28749,9 @@ function unavailable(message2, hint) {
28667
28749
  function findKeyHelper(opts) {
28668
28750
  const path = opts.override ?? opts.installed;
28669
28751
  if (!isAbsolute(path)) throw unavailable(`\u041F\u0443\u0442\u044C \u043A \u0445\u0435\u043B\u043F\u0435\u0440\u0443 ${path} \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u0430\u0431\u0441\u043E\u043B\u044E\u0442\u043D\u044B\u043C`, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043F\u043E\u043B\u043D\u044B\u0439 \u043F\u0443\u0442\u044C \u0432 SBERPAY_KEY_HELPER");
28670
- if (!existsSync4(path)) return void 0;
28752
+ if (!existsSync5(path)) return void 0;
28671
28753
  if (!isTrustedFile(path)) {
28672
- throw unavailable(`\u0425\u0435\u043B\u043F\u0435\u0440 ${path} \u043D\u0435 \u043F\u0440\u0438\u043D\u0430\u0434\u043B\u0435\u0436\u0438\u0442 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044E \u0438\u043B\u0438 \u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D \u043D\u0430 \u0437\u0430\u043F\u0438\u0441\u044C \u0434\u0440\u0443\u0433\u0438\u043C`, "\u041F\u0435\u0440\u0435\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0435 sberpay-cli; \u043F\u0440\u0430\u0432\u0430 \u043D\u0430 \u0445\u0435\u043B\u043F\u0435\u0440 \u0438 \u0435\u0433\u043E \u043A\u0430\u0442\u0430\u043B\u043E\u0433 \u2014 0755, \u0432\u043B\u0430\u0434\u0435\u043B\u0435\u0446 \u2014 \u0432\u044B \u0438\u043B\u0438 root");
28754
+ throw unavailable(`\u0425\u0435\u043B\u043F\u0435\u0440 ${path} \u043D\u0435 \u043F\u0440\u0438\u043D\u0430\u0434\u043B\u0435\u0436\u0438\u0442 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044E \u0438\u043B\u0438 \u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D \u043D\u0430 \u0437\u0430\u043F\u0438\u0441\u044C \u0434\u0440\u0443\u0433\u0438\u043C`, "\u041F\u0435\u0440\u0435\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0435 sberpay-cli; \u043F\u0440\u0430\u0432\u0430 \u043D\u0430 \u0445\u0435\u043B\u043F\u0435\u0440 \u0438 \u0435\u0433\u043E \u043A\u0430\u0442\u0430\u043B\u043E\u0433: Unix 0755; Windows \u2014 \u0437\u0430\u043F\u0438\u0441\u044C \u0442\u043E\u043B\u044C\u043A\u043E \u0432\u043B\u0430\u0434\u0435\u043B\u044C\u0446\u0443, SYSTEM \u0438 Administrators");
28673
28755
  }
28674
28756
  return path;
28675
28757
  }
@@ -28735,9 +28817,14 @@ function osSecretStore(standName, stand, opts = {}) {
28735
28817
  }
28736
28818
  function fileSecretStore(paths, stand) {
28737
28819
  const file2 = join5(paths.configDir, `secrets.${stand}.json`);
28738
- const read = () => existsSync5(file2) ? JSON.parse(readFileSync5(file2, "utf8")) : {};
28820
+ const read = () => {
28821
+ if (!existsSync6(file2)) return {};
28822
+ if (process.platform === "win32") assertWindowsPrivatePath(file2);
28823
+ return JSON.parse(readFileSync5(file2, "utf8"));
28824
+ };
28739
28825
  const write = (data) => {
28740
- mkdirSync4(paths.configDir, { recursive: true, mode: 448 });
28826
+ if (process.platform === "win32") ensureWindowsPrivateDirectory(paths.configDir);
28827
+ else mkdirSync4(paths.configDir, { recursive: true, mode: 448 });
28741
28828
  if (Object.keys(data).length === 0) return rmSync4(file2, { force: true });
28742
28829
  const tmp = `${file2}.${process.pid}.tmp`;
28743
28830
  writeFileSync3(tmp, JSON.stringify(data), { mode: 384 });
@@ -28764,8 +28851,12 @@ function openSecretStore(paths, standName, stand, opts = {}) {
28764
28851
  // packages/cli/src/core/context.ts
28765
28852
  var DEFAULT_LOGGING = join6(BUILD.root, "config", "logging.yaml");
28766
28853
  function fileSink(paths, verbose) {
28767
- mkdirSync5(paths.stateDir, { recursive: true, mode: 448 });
28854
+ if (process.platform === "win32") ensureWindowsPrivateDirectory(paths.stateDir);
28855
+ else mkdirSync5(paths.stateDir, { recursive: true, mode: 448 });
28768
28856
  const logFile = join6(paths.stateDir, "cli.log");
28857
+ if (process.platform === "win32") {
28858
+ if (existsSync7(logFile)) assertWindowsPrivatePath(logFile);
28859
+ }
28769
28860
  return (line) => {
28770
28861
  appendFileSync(logFile, `${line}
28771
28862
  `, { mode: 384 });
@@ -28784,6 +28875,7 @@ var netLogger = (sink) => {
28784
28875
  function buildCoreContext(opts, overridePaths) {
28785
28876
  const out = createOutput(Boolean(opts.json));
28786
28877
  const paths = overridePaths ?? cliPaths();
28878
+ if (process.platform === "win32") for (const path of Object.values(paths)) ensureWindowsPrivateDirectory(path);
28787
28879
  const config2 = loadConfig(paths);
28788
28880
  const requested = opts.stand ?? config2.stand;
28789
28881
  if (!isStand(requested)) throw new CliError(EXIT.VALIDATION, "INVALID_ARGUMENT", `\u041D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u044B\u0439 \u0441\u0442\u0435\u043D\u0434 \xAB${requested}\xBB: ${STAND_NAMES.join(", ")}`);
@@ -28812,7 +28904,7 @@ function buildCoreContext(opts, overridePaths) {
28812
28904
  }
28813
28905
 
28814
28906
  // packages/cli/src/schemes/v2/deviceKeys.ts
28815
- import { existsSync as existsSync6 } from "node:fs";
28907
+ import { existsSync as existsSync8 } from "node:fs";
28816
28908
  import { join as join7 } from "node:path";
28817
28909
  var DEVICE_SECRETS = ["deviceSignKey", "deviceEncKey"];
28818
28910
  var SOFTWARE_ORDER = ["hardware", "os", "file"];
@@ -28850,6 +28942,7 @@ async function selectDeviceKeys(core, sel = {}) {
28850
28942
  const backend = keyHelperBackend(platform2);
28851
28943
  const hint = backend ? keyHelperBuildHint(backend) : `\u041D\u0430 ${platform2} \u0430\u043F\u043F\u0430\u0440\u0430\u0442\u043D\u044B\u0445 \u043A\u043B\u044E\u0447\u0435\u0439 \u043D\u0435\u0442`;
28852
28944
  const hardwareFile = backend && hardwareKeyFile(core, backend.kind);
28945
+ if (process.platform === "win32" && hardwareFile && existsSync8(hardwareFile)) assertWindowsPrivatePath(hardwareFile);
28853
28946
  let helperLookup;
28854
28947
  const keyHelper = () => {
28855
28948
  helperLookup ??= { path: backend && findKeyHelper({ override: overrides.SBERPAY_KEY_HELPER, installed: sel.installedHelper ?? backend.path }) };
@@ -28868,7 +28961,7 @@ async function selectDeviceKeys(core, sel = {}) {
28868
28961
  const cached2 = probes.get(storage);
28869
28962
  if (cached2) return cached2;
28870
28963
  const result = (() => {
28871
- if (storage === "hardware") return { ok: true, hasKeys: Boolean(hardwareFile && existsSync6(hardwareFile)) };
28964
+ if (storage === "hardware") return { ok: true, hasKeys: Boolean(hardwareFile && existsSync8(hardwareFile)) };
28872
28965
  try {
28873
28966
  return { ok: true, hasKeys: stores[storage]().get(SIGN_KEY_NAME) !== void 0 };
28874
28967
  } catch {
@@ -29234,7 +29327,7 @@ function ensureTrustFor(url2, store = tls, roots = PINNED_ROOTS, now = /* @__PUR
29234
29327
  }
29235
29328
 
29236
29329
  // packages/cli/src/core/version.ts
29237
- var CLI_VERSION = "0.4.0-dev.5";
29330
+ var CLI_VERSION = "0.4.0-dev.8";
29238
29331
 
29239
29332
  // packages/cli/src/core/http.ts
29240
29333
  var USER_AGENT = `sberpay-cli/${CLI_VERSION}`;