@sberpay-cli/cli-diagnostic 0.4.0-dev.7 → 0.4.0-dev.9
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/build-info.json +4 -4
- package/dist/npm-entry.mjs +191 -100
- package/manifest.json +8 -7
- package/package/SHA256SUMS +5 -4
- package/package/dist/binding-worker.mjs +29 -8
- package/package/dist/cli.mjs +600 -97
- package/package/package.json +1 -1
- package/package/skill/sberpay/SKILL.md +27 -2
- package/package/skill/sberpay/scripts/approved-message.mjs +79 -0
- package/package.json +1 -1
package/build-info.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"profile": "diagnostic",
|
|
3
|
-
"version": "0.4.0-dev.
|
|
4
|
-
"sourceCommit": "
|
|
5
|
-
"sourceTreeDigest": "
|
|
3
|
+
"version": "0.4.0-dev.9",
|
|
4
|
+
"sourceCommit": "db0ec0c6594c1d28d55158cde8f6e5d564251e46",
|
|
5
|
+
"sourceTreeDigest": "5f12d63abb08dee373fbdd3ffd173836b8efbaa8d84886af05d5e85c3401db46",
|
|
6
6
|
"snapshot": false,
|
|
7
|
-
"buildId": "
|
|
7
|
+
"buildId": "81921baa6ca1b7998a4feb445c67515af5251419e7bd514bc95dd70384c32abd",
|
|
8
8
|
"stateFormat": 2
|
|
9
9
|
}
|
package/dist/npm-entry.mjs
CHANGED
|
@@ -106,7 +106,7 @@ var require_polyfills = __commonJS({
|
|
|
106
106
|
}
|
|
107
107
|
if (platform === "win32") {
|
|
108
108
|
fs.rename = typeof fs.rename !== "function" ? fs.rename : (function(fs$rename) {
|
|
109
|
-
function
|
|
109
|
+
function rename8(from, to, cb) {
|
|
110
110
|
var start = Date.now();
|
|
111
111
|
var backoff = 0;
|
|
112
112
|
fs$rename(from, to, function CB(er) {
|
|
@@ -126,8 +126,8 @@ var require_polyfills = __commonJS({
|
|
|
126
126
|
if (cb) cb(er);
|
|
127
127
|
});
|
|
128
128
|
}
|
|
129
|
-
if (Object.setPrototypeOf) Object.setPrototypeOf(
|
|
130
|
-
return
|
|
129
|
+
if (Object.setPrototypeOf) Object.setPrototypeOf(rename8, fs$rename);
|
|
130
|
+
return rename8;
|
|
131
131
|
})(fs.rename);
|
|
132
132
|
}
|
|
133
133
|
fs.read = typeof fs.read !== "function" ? fs.read : (function(fs$read) {
|
|
@@ -531,8 +531,8 @@ var require_graceful_fs = __commonJS({
|
|
|
531
531
|
fs2.createReadStream = createReadStream;
|
|
532
532
|
fs2.createWriteStream = createWriteStream;
|
|
533
533
|
var fs$readFile = fs2.readFile;
|
|
534
|
-
fs2.readFile =
|
|
535
|
-
function
|
|
534
|
+
fs2.readFile = readFile5;
|
|
535
|
+
function readFile5(path, options, cb) {
|
|
536
536
|
if (typeof options === "function")
|
|
537
537
|
cb = options, options = null;
|
|
538
538
|
return go$readFile(path, options, cb);
|
|
@@ -548,8 +548,8 @@ var require_graceful_fs = __commonJS({
|
|
|
548
548
|
}
|
|
549
549
|
}
|
|
550
550
|
var fs$writeFile = fs2.writeFile;
|
|
551
|
-
fs2.writeFile =
|
|
552
|
-
function
|
|
551
|
+
fs2.writeFile = writeFile5;
|
|
552
|
+
function writeFile5(path, data, options, cb) {
|
|
553
553
|
if (typeof options === "function")
|
|
554
554
|
cb = options, options = null;
|
|
555
555
|
return go$writeFile(path, data, options, cb);
|
|
@@ -708,7 +708,7 @@ var require_graceful_fs = __commonJS({
|
|
|
708
708
|
}
|
|
709
709
|
function ReadStream$open() {
|
|
710
710
|
var that = this;
|
|
711
|
-
|
|
711
|
+
open9(that.path, that.flags, that.mode, function(err, fd) {
|
|
712
712
|
if (err) {
|
|
713
713
|
if (that.autoClose)
|
|
714
714
|
that.destroy();
|
|
@@ -728,7 +728,7 @@ var require_graceful_fs = __commonJS({
|
|
|
728
728
|
}
|
|
729
729
|
function WriteStream$open() {
|
|
730
730
|
var that = this;
|
|
731
|
-
|
|
731
|
+
open9(that.path, that.flags, that.mode, function(err, fd) {
|
|
732
732
|
if (err) {
|
|
733
733
|
that.destroy();
|
|
734
734
|
that.emit("error", err);
|
|
@@ -745,8 +745,8 @@ var require_graceful_fs = __commonJS({
|
|
|
745
745
|
return new fs2.WriteStream(path, options);
|
|
746
746
|
}
|
|
747
747
|
var fs$open = fs2.open;
|
|
748
|
-
fs2.open =
|
|
749
|
-
function
|
|
748
|
+
fs2.open = open9;
|
|
749
|
+
function open9(path, flags, mode, cb) {
|
|
750
750
|
if (typeof mode === "function")
|
|
751
751
|
cb = mode, mode = null;
|
|
752
752
|
return go$open(path, flags, mode, cb);
|
|
@@ -1617,8 +1617,8 @@ var require_proper_lockfile = __commonJS({
|
|
|
1617
1617
|
});
|
|
1618
1618
|
|
|
1619
1619
|
// scripts/diagnostics/npm-entry.mts
|
|
1620
|
-
import { readFile as
|
|
1621
|
-
import { dirname as dirname7, join as
|
|
1620
|
+
import { readFile as readFile4 } from "node:fs/promises";
|
|
1621
|
+
import { dirname as dirname7, join as join12 } from "node:path";
|
|
1622
1622
|
import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
1623
1623
|
import { homedir as homedir4 } from "node:os";
|
|
1624
1624
|
|
|
@@ -2348,9 +2348,9 @@ function floatSafeRemainder(val, step) {
|
|
|
2348
2348
|
return ratio - roundedRatio;
|
|
2349
2349
|
}
|
|
2350
2350
|
var EVALUATING = /* @__PURE__ */ Symbol("evaluating");
|
|
2351
|
-
function defineLazy(
|
|
2351
|
+
function defineLazy(object3, key, getter) {
|
|
2352
2352
|
let value = void 0;
|
|
2353
|
-
Object.defineProperty(
|
|
2353
|
+
Object.defineProperty(object3, key, {
|
|
2354
2354
|
get() {
|
|
2355
2355
|
if (value === EVALUATING) {
|
|
2356
2356
|
return void 0;
|
|
@@ -2362,7 +2362,7 @@ function defineLazy(object2, key, getter) {
|
|
|
2362
2362
|
return value;
|
|
2363
2363
|
},
|
|
2364
2364
|
set(v) {
|
|
2365
|
-
Object.defineProperty(
|
|
2365
|
+
Object.defineProperty(object3, key, {
|
|
2366
2366
|
value: v
|
|
2367
2367
|
// configurable: true,
|
|
2368
2368
|
});
|
|
@@ -17429,8 +17429,8 @@ function foldObjects(members2) {
|
|
|
17429
17429
|
}
|
|
17430
17430
|
const properties = {};
|
|
17431
17431
|
const required2 = /* @__PURE__ */ new Set();
|
|
17432
|
-
for (const
|
|
17433
|
-
for (const key in
|
|
17432
|
+
for (const object3 of objects) {
|
|
17433
|
+
for (const key in object3.properties) {
|
|
17434
17434
|
if (Object.prototype.hasOwnProperty.call(properties, key))
|
|
17435
17435
|
continue;
|
|
17436
17436
|
const parts = [];
|
|
@@ -17444,18 +17444,18 @@ function foldObjects(members2) {
|
|
|
17444
17444
|
const merged = parts.length === 1 ? parts[0] : foldObjects(parts) ?? { allOf: parts };
|
|
17445
17445
|
assignProp(properties, key, merged);
|
|
17446
17446
|
}
|
|
17447
|
-
for (const key of
|
|
17447
|
+
for (const key of object3.required ?? [])
|
|
17448
17448
|
required2.add(key);
|
|
17449
17449
|
}
|
|
17450
17450
|
const folded = { type: "object", properties };
|
|
17451
17451
|
if (required2.size)
|
|
17452
17452
|
folded.required = [...required2];
|
|
17453
|
-
if (objects.every((
|
|
17453
|
+
if (objects.every((object3) => object3.additionalProperties === false)) {
|
|
17454
17454
|
folded.additionalProperties = false;
|
|
17455
17455
|
} else {
|
|
17456
17456
|
const constraints = [];
|
|
17457
|
-
for (const
|
|
17458
|
-
const constraint = undeclaredConstraint(
|
|
17457
|
+
for (const object3 of objects) {
|
|
17458
|
+
const constraint = undeclaredConstraint(object3);
|
|
17459
17459
|
if (constraint && !constraints.some((seen) => JSON.stringify(seen) === JSON.stringify(constraint)))
|
|
17460
17460
|
constraints.push(constraint);
|
|
17461
17461
|
}
|
|
@@ -21374,7 +21374,7 @@ function skillFileHashes(skill, files, platform = process.platform) {
|
|
|
21374
21374
|
}
|
|
21375
21375
|
function renderDiagnosticSkill(source2, platform, launcher, node2) {
|
|
21376
21376
|
if (platform === "win32") source2 = source2.replace(/(\{\{diagnosticLauncher\}\} auth complete --json) <<'TOKEN'\n([\s\S]*?)\nTOKEN/g, "@'\n$2\n'@ | $1").replace(/\\\r?\n\s*/g, " ");
|
|
21377
|
-
return source2.replaceAll("{{diagnosticLauncher}}", diagnosticLauncherCommand(platform, launcher, node2)) + (platform === "win32" ? "\n\u041D\u0430 Windows \u043A\u043E\u043C\u0430\u043D\u0434\u044B \u0432\u044B\u0448\u0435 \u0432\u044B\u043F\u043E\u043B\u043D\u044F\u044E\u0442\u0441\u044F \u0432 PowerShell. \
|
|
21377
|
+
return source2.replaceAll("{{diagnosticLauncher}}", diagnosticLauncherCommand(platform, launcher, node2)) + (platform === "win32" ? "\n\u041D\u0430 Windows \u043A\u043E\u043C\u0430\u043D\u0434\u044B \u0432\u044B\u0448\u0435 \u0432\u044B\u043F\u043E\u043B\u043D\u044F\u044E\u0442\u0441\u044F \u0432 PowerShell. \u041F\u0440\u0438\u0432\u044F\u0437\u043A\u0435 \u043A \u0447\u0430\u0442\u0443 Claude Code \u0445\u0443\u043A SessionStart \u0438 Git Bash \u043D\u0435 \u043D\u0443\u0436\u043D\u044B.\n" : "");
|
|
21378
21378
|
}
|
|
21379
21379
|
|
|
21380
21380
|
// packages/cli/src/core/paths.ts
|
|
@@ -21418,7 +21418,7 @@ import { join as join2 } from "node:path";
|
|
|
21418
21418
|
import { mkdirSync, existsSync, openSync, writeFileSync, fsyncSync, closeSync, renameSync, rmSync } from "node:fs";
|
|
21419
21419
|
import { dirname as dirname2 } from "node:path";
|
|
21420
21420
|
import { randomUUID } from "node:crypto";
|
|
21421
|
-
function atomicJson(path, value) {
|
|
21421
|
+
function atomicJson(path, value, options = {}) {
|
|
21422
21422
|
if (process.platform === "win32") {
|
|
21423
21423
|
ensureWindowsPrivateDirectory(dirname2(path));
|
|
21424
21424
|
if (existsSync(path)) assertWindowsPrivatePath(path);
|
|
@@ -21427,7 +21427,7 @@ function atomicJson(path, value) {
|
|
|
21427
21427
|
try {
|
|
21428
21428
|
const fd = openSync(temp, "wx", 384);
|
|
21429
21429
|
try {
|
|
21430
|
-
writeFileSync(fd, JSON.stringify(value, null, 2) + "\n");
|
|
21430
|
+
writeFileSync(fd, (options.compact ? JSON.stringify(value) : JSON.stringify(value, null, 2)) + "\n");
|
|
21431
21431
|
fsyncSync(fd);
|
|
21432
21432
|
} finally {
|
|
21433
21433
|
closeSync(fd);
|
|
@@ -21876,7 +21876,7 @@ async function exclusive(paths, recover, fn, installing2 = false) {
|
|
|
21876
21876
|
JSON.stringify({ pid: process.pid }),
|
|
21877
21877
|
{ mode: 384, flag: "wx" }
|
|
21878
21878
|
);
|
|
21879
|
-
const fd = openSync4(join5(lock, "owner.json"), "r");
|
|
21879
|
+
const fd = openSync4(join5(lock, "owner.json"), "r+");
|
|
21880
21880
|
try {
|
|
21881
21881
|
fsyncSync3(fd);
|
|
21882
21882
|
} finally {
|
|
@@ -22220,13 +22220,23 @@ import { createHash as createHash4 } from "node:crypto";
|
|
|
22220
22220
|
var windowsArgument = (s) => '"' + s.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/, "$1$1") + '"';
|
|
22221
22221
|
function windowsSenderConfig(home, launcher, node2) {
|
|
22222
22222
|
if (!win323.isAbsolute(launcher) || !win323.isAbsolute(node2) || /[\0\r\n]/.test(launcher + node2)) throw Error("INVALID_SENDER_PATH");
|
|
22223
|
-
return { path: win323.join(home, ".local", "share", "sberpay-diagnostic", "sender-task.json"), text: JSON.stringify({
|
|
22223
|
+
return { path: win323.join(home, ".local", "share", "sberpay-diagnostic", "sender-task.json"), text: JSON.stringify({
|
|
22224
|
+
name: "SberPay.Diagnostic." + createHash4("sha256").update(launcher.toLowerCase()).digest("hex").slice(0, 24),
|
|
22225
|
+
node: node2,
|
|
22226
|
+
launcher,
|
|
22227
|
+
arguments: windowsArgument(launcher) + " report flush --json",
|
|
22228
|
+
// node.exe is a console program: started by Task Scheduler in the user's session it opens a console window every
|
|
22229
|
+
// 5 minutes. conhost.exe --headless hosts the same process without a window; same user, token and arguments.
|
|
22230
|
+
headlessArguments: "--headless " + windowsArgument(node2) + " " + windowsArgument(launcher) + " report flush --json"
|
|
22231
|
+
}) };
|
|
22224
22232
|
}
|
|
22225
22233
|
var SCRIPT2 = String.raw`
|
|
22226
22234
|
$ErrorActionPreference='Stop'
|
|
22227
22235
|
[Console]::OutputEncoding=New-Object System.Text.UTF8Encoding($false)
|
|
22228
22236
|
$c=Get-Content -LiteralPath $env:SBERPAY_SENDER_CONFIG -Raw -Encoding UTF8|ConvertFrom-Json
|
|
22229
22237
|
$sid=[Security.Principal.WindowsIdentity]::GetCurrent().User.Value
|
|
22238
|
+
# Task Scheduler reads Principal.UserId back as an account name ("julia"), not the SID it was registered with.
|
|
22239
|
+
function SidOf($u){if(!$u){return $null};if($u -match '^S-1-'){return $u};try{return (New-Object Security.Principal.NTAccount($u)).Translate([Security.Principal.SecurityIdentifier]).Value}catch{return $null}}
|
|
22230
22240
|
$service=New-Object -ComObject 'Schedule.Service'
|
|
22231
22241
|
$service.Connect()
|
|
22232
22242
|
$folder=$service.GetFolder('\')
|
|
@@ -22234,7 +22244,7 @@ $source='sberpay-diagnostic:'+ $c.launcher
|
|
|
22234
22244
|
$existing=$null
|
|
22235
22245
|
try{$existing=$folder.GetTask($c.name)}catch{$e=$_.Exception;while($e.InnerException){$e=$e.InnerException};if($e.HResult -ne -2147024894){throw}}
|
|
22236
22246
|
if($existing){
|
|
22237
|
-
if($existing.Definition.RegistrationInfo.Source -cne $source -or $existing.Definition.Principal.UserId -ne $sid){throw 'SENDER_TASK_CONFLICT'}
|
|
22247
|
+
if($existing.Definition.RegistrationInfo.Source -cne $source -or (SidOf $existing.Definition.Principal.UserId) -ne $sid){throw 'SENDER_TASK_CONFLICT'}
|
|
22238
22248
|
}
|
|
22239
22249
|
$task=$service.NewTask(0)
|
|
22240
22250
|
$task.RegistrationInfo.Source=$source
|
|
@@ -22256,15 +22266,18 @@ $timer.Enabled=$true
|
|
|
22256
22266
|
$logon=$task.Triggers.Create(9)
|
|
22257
22267
|
$logon.UserId=$sid
|
|
22258
22268
|
$logon.Enabled=$true
|
|
22269
|
+
# Hidden console: the system conhost.exe hosts node without a window. Without it, fall back to node itself.
|
|
22270
|
+
$conhost=[IO.Path]::Combine($env:SystemRoot,'System32','conhost.exe')
|
|
22271
|
+
if($c.headlessArguments -and (Test-Path -LiteralPath $conhost -PathType Leaf)){$program=$conhost;$programArguments=$c.headlessArguments}else{$program=$c.node;$programArguments=$c.arguments}
|
|
22259
22272
|
$action=$task.Actions.Create(0)
|
|
22260
|
-
$action.Path=$
|
|
22261
|
-
$action.Arguments=$
|
|
22273
|
+
$action.Path=$program
|
|
22274
|
+
$action.Arguments=$programArguments
|
|
22262
22275
|
$action.WorkingDirectory=[IO.Path]::GetDirectoryName($c.launcher)
|
|
22263
22276
|
$registered=$folder.RegisterTaskDefinition($c.name,$task,6,$sid,$null,3,$null)
|
|
22264
22277
|
$read=$folder.GetTask($c.name)
|
|
22265
22278
|
$d=$read.Definition
|
|
22266
|
-
if($d.Settings.ExecutionTimeLimit -ne 'PT0S' -or $d.Settings.MultipleInstances -ne 2 -or !$read.Enabled -or $d.Principal.UserId -ne $sid -or $d.Principal.LogonType -ne 3 -or $d.Principal.RunLevel -ne 0 -or $d.Actions.Count -ne 1 -or $d.Actions.Item(1).Path -cne $
|
|
22267
|
-
@{status='active';taskName=$c.name}|ConvertTo-Json -Compress
|
|
22279
|
+
if($d.Settings.ExecutionTimeLimit -ne 'PT0S' -or $d.Settings.MultipleInstances -ne 2 -or !$read.Enabled -or (SidOf $d.Principal.UserId) -ne $sid -or $d.Principal.LogonType -ne 3 -or $d.Principal.RunLevel -ne 0 -or $d.Actions.Count -ne 1 -or $d.Actions.Item(1).Path -cne $program -or $d.Actions.Item(1).Arguments -cne $programArguments -or $d.Triggers.Count -ne 2 -or $d.Triggers.Item(1).Repetition.Interval -ne 'PT5M'){throw 'SENDER_TASK_NOT_ACTIVE'}
|
|
22280
|
+
@{status='active';taskName=$c.name;hidden=($program -ceq $conhost)}|ConvertTo-Json -Compress
|
|
22268
22281
|
`;
|
|
22269
22282
|
function windowsSenderCommand(path, env = process.env) {
|
|
22270
22283
|
if (!env.SystemRoot || !win323.isAbsolute(env.SystemRoot)) throw Error("WINDOWS_SYSTEM_ROOT_MISSING");
|
|
@@ -22345,6 +22358,81 @@ async function installSender(home, launcher) {
|
|
|
22345
22358
|
}
|
|
22346
22359
|
}
|
|
22347
22360
|
|
|
22361
|
+
// packages/cli/src/report/claudeHook.ts
|
|
22362
|
+
import { open as open7, chmod, lstat as lstat5, mkdir as mkdir4, readFile as readFile2, realpath, rename as rename6, writeFile as writeFile3 } from "node:fs/promises";
|
|
22363
|
+
import { join as join10 } from "node:path";
|
|
22364
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
22365
|
+
|
|
22366
|
+
// packages/cli/src/report/adapters/types.ts
|
|
22367
|
+
function object2(value) {
|
|
22368
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
22369
|
+
}
|
|
22370
|
+
|
|
22371
|
+
// packages/cli/src/report/claudeHook.ts
|
|
22372
|
+
var shellQuote = (text) => `'${text.replace(/'/g, "'\\''")}'`;
|
|
22373
|
+
var claudeHookCommandFor = (args) => [...args, "report", "claude-hook"].map((s) => shellQuote(process.platform === "win32" ? s.replaceAll("\\", "/") : s)).join(" ");
|
|
22374
|
+
var HOOK_SUFFIX = " 'report' 'claude-hook'";
|
|
22375
|
+
async function readSettings(configDir, create) {
|
|
22376
|
+
if (create) {
|
|
22377
|
+
if (process.platform === "win32") ensureWindowsPrivateDirectory(configDir);
|
|
22378
|
+
else await mkdir4(configDir, { recursive: true, mode: 448 });
|
|
22379
|
+
}
|
|
22380
|
+
const path = join10(configDir, "settings.json");
|
|
22381
|
+
let original;
|
|
22382
|
+
try {
|
|
22383
|
+
const info = await lstat5(path);
|
|
22384
|
+
if (!info.isFile() || info.isSymbolicLink()) throw new BindingError("UNSAFE_SETTINGS");
|
|
22385
|
+
if (process.platform === "win32") assertWindowsPrivatePath(path);
|
|
22386
|
+
original = await readFile2(path, "utf8");
|
|
22387
|
+
} catch (error62) {
|
|
22388
|
+
if (error62.code !== "ENOENT") throw error62;
|
|
22389
|
+
}
|
|
22390
|
+
const settings = original === void 0 ? {} : object2(JSON.parse(original));
|
|
22391
|
+
if (!settings) throw new BindingError("INVALID_SETTINGS");
|
|
22392
|
+
const hooks = settings.hooks === void 0 ? {} : object2(settings.hooks);
|
|
22393
|
+
if (!hooks) throw new BindingError("INVALID_HOOK_SETTINGS");
|
|
22394
|
+
const start = hooks.SessionStart === void 0 ? [] : hooks.SessionStart;
|
|
22395
|
+
if (!Array.isArray(start)) throw new BindingError("INVALID_HOOK_SETTINGS");
|
|
22396
|
+
return { path, original, settings, hooks, start };
|
|
22397
|
+
}
|
|
22398
|
+
async function writeSettings(path, original, settings) {
|
|
22399
|
+
const suffix = randomUUID7();
|
|
22400
|
+
if (original !== void 0) await writeFile3(`${path}.sberpay-${suffix}.bak`, original, { flag: "wx", mode: 384 });
|
|
22401
|
+
const temp = `${path}.sberpay-${suffix}.tmp`;
|
|
22402
|
+
await writeFile3(temp, JSON.stringify(settings, null, 2) + "\n", { flag: "wx", mode: 384 });
|
|
22403
|
+
await rename6(temp, path);
|
|
22404
|
+
await chmod(path, 384);
|
|
22405
|
+
}
|
|
22406
|
+
async function updateClaudeHook(configDir, command) {
|
|
22407
|
+
let read;
|
|
22408
|
+
try {
|
|
22409
|
+
read = await readSettings(configDir, false);
|
|
22410
|
+
} catch (error62) {
|
|
22411
|
+
if (error62.code === "ENOENT") return "absent";
|
|
22412
|
+
throw error62;
|
|
22413
|
+
}
|
|
22414
|
+
const { path, original, settings, start } = read;
|
|
22415
|
+
if (original === void 0) return "absent";
|
|
22416
|
+
let found = false, changed = false;
|
|
22417
|
+
for (const entry of start) {
|
|
22418
|
+
const group = object2(entry);
|
|
22419
|
+
if (!group || !Array.isArray(group.hooks)) continue;
|
|
22420
|
+
for (const value of group.hooks) {
|
|
22421
|
+
const hook = object2(value);
|
|
22422
|
+
if (hook?.type !== "command" || typeof hook.command !== "string" || !hook.command.endsWith(HOOK_SUFFIX) || !hook.command.includes("sberpay-diagnostic")) continue;
|
|
22423
|
+
found = true;
|
|
22424
|
+
if (hook.command !== command) {
|
|
22425
|
+
hook.command = command;
|
|
22426
|
+
changed = true;
|
|
22427
|
+
}
|
|
22428
|
+
}
|
|
22429
|
+
}
|
|
22430
|
+
if (!found) return "absent";
|
|
22431
|
+
if (!changed) return "current";
|
|
22432
|
+
await writeSettings(path, original, settings);
|
|
22433
|
+
return "updated";
|
|
22434
|
+
}
|
|
22435
|
+
|
|
22348
22436
|
// packages/cli/src/setup/steps.ts
|
|
22349
22437
|
var MIN_NODE_MINOR = { 22: 19, 24: 5 };
|
|
22350
22438
|
var LAST_LISTED_MAJOR = 24;
|
|
@@ -22353,27 +22441,27 @@ var LAST_LISTED_MAJOR = 24;
|
|
|
22353
22441
|
import { constants as constants4 } from "node:fs";
|
|
22354
22442
|
import { pathToFileURL } from "node:url";
|
|
22355
22443
|
import { homedir as homedir3 } from "node:os";
|
|
22356
|
-
import { join as
|
|
22357
|
-
import { mkdir as
|
|
22358
|
-
import { createHash as createHash5, randomUUID as
|
|
22444
|
+
import { join as join11, resolve, dirname as dirname6 } from "node:path";
|
|
22445
|
+
import { mkdir as mkdir5, readFile as readFile3, writeFile as writeFile4, lstat as lstat6, rename as rename7, rm as rm6, cp, open as open8, chmod as chmod2 } from "node:fs/promises";
|
|
22446
|
+
import { createHash as createHash5, randomUUID as randomUUID8 } from "node:crypto";
|
|
22359
22447
|
var hash3 = (text) => createHash5("sha256").update(text).digest("hex");
|
|
22360
22448
|
var Manifest2 = external_exports.object({ schemaVersion: external_exports.literal(1), buildId: external_exports.string().regex(/^[a-f0-9]{64}$/), setupHash: external_exports.string().regex(/^[a-f0-9]{64}$/).optional(), files: external_exports.record(external_exports.string(), external_exports.string().regex(/^[a-f0-9]{64}$/)) }).strict();
|
|
22361
22449
|
async function regular(path) {
|
|
22362
|
-
const s = await
|
|
22450
|
+
const s = await lstat6(path);
|
|
22363
22451
|
if (!s.isFile() || s.isSymbolicLink()) throw Error("UNSAFE_PACKAGE");
|
|
22364
22452
|
}
|
|
22365
22453
|
async function atomic(path, text, mode = 384) {
|
|
22366
|
-
const temp = path + "." +
|
|
22454
|
+
const temp = path + "." + randomUUID8() + ".tmp";
|
|
22367
22455
|
try {
|
|
22368
|
-
await
|
|
22369
|
-
await
|
|
22456
|
+
await writeFile4(temp, text, { flag: "wx", mode });
|
|
22457
|
+
await rename7(temp, path);
|
|
22370
22458
|
} finally {
|
|
22371
22459
|
await rm6(temp, { force: true });
|
|
22372
22460
|
}
|
|
22373
22461
|
}
|
|
22374
22462
|
async function installDiagnostic(source2, home = homedir3(), options = {}) {
|
|
22375
|
-
const root2 = privateDir2(
|
|
22376
|
-
return withInstallLock(root2, () => withPaymentLock(cliPaths({ SBERPAY_CLI_HOME:
|
|
22463
|
+
const root2 = privateDir2(join11(home, ".local", "share", "sberpay-diagnostic"));
|
|
22464
|
+
return withInstallLock(root2, () => withPaymentLock(cliPaths({ SBERPAY_CLI_HOME: join11(root2, "profile") }), () => installLocked(source2, home, options), true));
|
|
22377
22465
|
}
|
|
22378
22466
|
async function installLocked(source2, home, options) {
|
|
22379
22467
|
const enroll = typeof options === "function" ? options : options.enrollInvitation ?? enrollInvitation;
|
|
@@ -22381,15 +22469,15 @@ async function installLocked(source2, home, options) {
|
|
|
22381
22469
|
if (!(major > LAST_LISTED_MAJOR || MIN_NODE_MINOR[major] !== void 0 && minor >= MIN_NODE_MINOR[major])) throw Error("UNSUPPORTED_RUNTIME");
|
|
22382
22470
|
source2 = resolve(source2);
|
|
22383
22471
|
try {
|
|
22384
|
-
const info = JSON.parse(await
|
|
22472
|
+
const info = JSON.parse(await readFile3(join11(source2, "build-info.json"), "utf8"));
|
|
22385
22473
|
if (info.profile !== "diagnostic" || info.stateFormat !== 2) throw Error();
|
|
22386
22474
|
} catch {
|
|
22387
22475
|
throw Error("INCOMPATIBLE_STATE_FORMAT");
|
|
22388
22476
|
}
|
|
22389
|
-
const packageRoot =
|
|
22390
|
-
await regular(
|
|
22391
|
-
const manifest = Manifest2.parse(JSON.parse(await
|
|
22392
|
-
if (manifest.setupHash && hash3(await
|
|
22477
|
+
const packageRoot = join11(source2, "package");
|
|
22478
|
+
await regular(join11(source2, "manifest.json"));
|
|
22479
|
+
const manifest = Manifest2.parse(JSON.parse(await readFile3(join11(source2, "manifest.json"), "utf8")));
|
|
22480
|
+
if (manifest.setupHash && hash3(await readFile3(join11(source2, "dist/npm-entry.mjs"))) !== manifest.setupHash) throw Error("PACKAGE_HASH_MISMATCH");
|
|
22393
22481
|
const entries = Object.entries(manifest.files);
|
|
22394
22482
|
if (entries.length < 2 || entries.length > 1e3 || !manifest.files["dist/cli.mjs"] || !manifest.files["bin/sberpay-cli.mjs"] || !manifest.files["skill/sberpay/SKILL.md"]) throw Error("INVALID_MANIFEST");
|
|
22395
22483
|
for (const [path, digest] of entries) {
|
|
@@ -22397,17 +22485,17 @@ async function installLocked(source2, home, options) {
|
|
|
22397
22485
|
let cursor = packageRoot;
|
|
22398
22486
|
const parts = path.split("/");
|
|
22399
22487
|
for (const part of parts.slice(0, -1)) {
|
|
22400
|
-
cursor =
|
|
22401
|
-
const s = await
|
|
22488
|
+
cursor = join11(cursor, part);
|
|
22489
|
+
const s = await lstat6(cursor);
|
|
22402
22490
|
if (!s.isDirectory() || s.isSymbolicLink()) throw Error("UNSAFE_PACKAGE");
|
|
22403
22491
|
}
|
|
22404
|
-
await regular(
|
|
22405
|
-
if (hash3(await
|
|
22492
|
+
await regular(join11(packageRoot, path));
|
|
22493
|
+
if (hash3(await readFile3(join11(packageRoot, path))) !== digest) throw Error("PACKAGE_HASH_MISMATCH");
|
|
22406
22494
|
}
|
|
22407
22495
|
if (process.platform === "win32" && !manifest.files[`helpers/win32-${process.arch}/sberpay-tpm.exe`]) throw Error("WINDOWS_HELPER_NOT_PACKAGED");
|
|
22408
|
-
const root2 = privateDir2(
|
|
22409
|
-
const skill =
|
|
22410
|
-
const markerPath =
|
|
22496
|
+
const root2 = privateDir2(join11(home, ".local", "share", "sberpay-diagnostic"));
|
|
22497
|
+
const skill = join11(home, ".agents", "skills", "sberpay-diagnostic");
|
|
22498
|
+
const markerPath = join11(root2, "installed.json");
|
|
22411
22499
|
let prior;
|
|
22412
22500
|
try {
|
|
22413
22501
|
prior = JSON.parse((await privateRead(markerPath, 8192)).toString());
|
|
@@ -22416,20 +22504,20 @@ async function installLocked(source2, home, options) {
|
|
|
22416
22504
|
}
|
|
22417
22505
|
let pending;
|
|
22418
22506
|
try {
|
|
22419
|
-
pending = JSON.parse((await privateRead(
|
|
22507
|
+
pending = JSON.parse((await privateRead(join11(root2, "install-pending.json"), 1024 * 1024)).toString());
|
|
22420
22508
|
} catch (e) {
|
|
22421
22509
|
if (e.code !== "ENOENT") throw Error("INSTALLATION_STATE_INVALID");
|
|
22422
22510
|
}
|
|
22423
22511
|
if (pending && pending.buildId !== manifest.buildId) throw Error("INSTALLATION_CONFLICT");
|
|
22424
22512
|
if (prior?.stateFormat !== void 0 && ![1, 2].includes(prior.stateFormat)) throw Error("INCOMPATIBLE_STATE_FORMAT");
|
|
22425
|
-
const paymentPaths = cliPaths({ SBERPAY_CLI_HOME:
|
|
22513
|
+
const paymentPaths = cliPaths({ SBERPAY_CLI_HOME: join11(root2, "profile") });
|
|
22426
22514
|
const paymentModeFile = modeFile(paymentPaths);
|
|
22427
22515
|
let modeState;
|
|
22428
22516
|
if (prior?.stateFormat === 2) modeState = readPaymentMode(paymentPaths);
|
|
22429
22517
|
else {
|
|
22430
22518
|
let modeExists = false;
|
|
22431
22519
|
try {
|
|
22432
|
-
await
|
|
22520
|
+
await lstat6(paymentModeFile);
|
|
22433
22521
|
modeExists = true;
|
|
22434
22522
|
} catch (e) {
|
|
22435
22523
|
if (e.code !== "ENOENT") throw e;
|
|
@@ -22441,18 +22529,18 @@ async function installLocked(source2, home, options) {
|
|
|
22441
22529
|
}
|
|
22442
22530
|
const acceptedPending = (path, digest) => pending?.files.some((f) => f.path === path && (f.before === digest || f.after === digest));
|
|
22443
22531
|
try {
|
|
22444
|
-
const info = await
|
|
22532
|
+
const info = await lstat6(skill);
|
|
22445
22533
|
if (!info.isDirectory() || info.isSymbolicLink()) throw Error("SKILL_MODIFIED");
|
|
22446
|
-
const text2 = await
|
|
22447
|
-
if (!acceptedPending(
|
|
22534
|
+
const text2 = await readFile3(join11(skill, "SKILL.md"), "utf8");
|
|
22535
|
+
if (!acceptedPending(join11(skill, "SKILL.md"), hash3(text2)) && (!prior || hash3(text2) !== prior.skillHash && hash3(text2) !== prior.previousSkillHash)) throw Error("SKILL_MODIFIED");
|
|
22448
22536
|
} catch (error62) {
|
|
22449
22537
|
if (error62.code !== "ENOENT") throw error62;
|
|
22450
22538
|
}
|
|
22451
|
-
const releases = privateDir2(
|
|
22452
|
-
const release =
|
|
22539
|
+
const releases = privateDir2(join11(root2, "releases"));
|
|
22540
|
+
const release = join11(releases, manifest.buildId);
|
|
22453
22541
|
let exists = false;
|
|
22454
22542
|
try {
|
|
22455
|
-
const info = await
|
|
22543
|
+
const info = await lstat6(release);
|
|
22456
22544
|
if (!info.isDirectory() || info.isSymbolicLink()) throw Error("UNSAFE_RELEASE");
|
|
22457
22545
|
exists = true;
|
|
22458
22546
|
} catch (error62) {
|
|
@@ -22462,64 +22550,64 @@ async function installLocked(source2, home, options) {
|
|
|
22462
22550
|
for (const [path, digest] of entries) {
|
|
22463
22551
|
let cursor = release;
|
|
22464
22552
|
for (const part of path.split("/").slice(0, -1)) {
|
|
22465
|
-
cursor =
|
|
22466
|
-
const info = await
|
|
22553
|
+
cursor = join11(cursor, part);
|
|
22554
|
+
const info = await lstat6(cursor);
|
|
22467
22555
|
if (!info.isDirectory() || info.isSymbolicLink()) throw Error("UNSAFE_RELEASE");
|
|
22468
22556
|
}
|
|
22469
|
-
await regular(
|
|
22470
|
-
if (hash3(await
|
|
22557
|
+
await regular(join11(release, path));
|
|
22558
|
+
if (hash3(await readFile3(join11(release, path))) !== digest) throw Error("RELEASE_MODIFIED");
|
|
22471
22559
|
}
|
|
22472
22560
|
} else {
|
|
22473
|
-
const staged =
|
|
22474
|
-
await
|
|
22561
|
+
const staged = join11(releases, ".staging-" + randomUUID8());
|
|
22562
|
+
await mkdir5(staged, { mode: 448 });
|
|
22475
22563
|
try {
|
|
22476
22564
|
for (const [path] of entries) {
|
|
22477
|
-
const target =
|
|
22478
|
-
await
|
|
22479
|
-
await cp(
|
|
22480
|
-
await
|
|
22565
|
+
const target = join11(staged, path);
|
|
22566
|
+
await mkdir5(dirname6(target), { recursive: true, mode: 448 });
|
|
22567
|
+
await cp(join11(packageRoot, path), target, { force: false, errorOnExist: true });
|
|
22568
|
+
await chmod2(target, /^helpers\/[^/]+\/sberpay-(se|tpm)(\.exe)?$/.test(path) ? 448 : 384);
|
|
22481
22569
|
}
|
|
22482
|
-
await
|
|
22570
|
+
await rename7(staged, release);
|
|
22483
22571
|
} finally {
|
|
22484
22572
|
await rm6(staged, { recursive: true, force: true });
|
|
22485
22573
|
}
|
|
22486
22574
|
}
|
|
22487
|
-
const profile = privateDir2(
|
|
22575
|
+
const profile = privateDir2(join11(root2, "profile"));
|
|
22488
22576
|
let hasInvitation = false;
|
|
22489
22577
|
try {
|
|
22490
|
-
await regular(
|
|
22578
|
+
await regular(join11(source2, "invitation.json"));
|
|
22491
22579
|
hasInvitation = true;
|
|
22492
22580
|
} catch (error62) {
|
|
22493
22581
|
if (error62.code !== "ENOENT") throw error62;
|
|
22494
22582
|
}
|
|
22495
22583
|
if (hasInvitation) {
|
|
22496
|
-
const invitationFile = await
|
|
22584
|
+
const invitationFile = await open8(join11(source2, "invitation.json"), constants4.O_RDONLY | constants4.O_NOFOLLOW | constants4.O_NONBLOCK);
|
|
22497
22585
|
try {
|
|
22498
22586
|
const info = await invitationFile.stat();
|
|
22499
22587
|
if (!info.isFile() || process.getuid && info.uid !== process.getuid()) throw Error("UNSAFE_INVITATION");
|
|
22500
|
-
if (process.platform === "win32") assertWindowsPrivatePath(
|
|
22588
|
+
if (process.platform === "win32") assertWindowsPrivatePath(join11(source2, "invitation.json"));
|
|
22501
22589
|
else await invitationFile.chmod(384);
|
|
22502
22590
|
} finally {
|
|
22503
22591
|
await invitationFile.close();
|
|
22504
22592
|
}
|
|
22505
|
-
await enroll(
|
|
22593
|
+
await enroll(join11(source2, "invitation.json"), { ...process.env, SBERPAY_CLI_HOME: profile });
|
|
22506
22594
|
} else {
|
|
22507
22595
|
let hasCredential = false;
|
|
22508
22596
|
try {
|
|
22509
|
-
await regular(
|
|
22597
|
+
await regular(join11(profile, "config", "report-upload.json"));
|
|
22510
22598
|
hasCredential = true;
|
|
22511
22599
|
} catch (e) {
|
|
22512
22600
|
if (e.code !== "ENOENT") throw e;
|
|
22513
22601
|
}
|
|
22514
22602
|
if (hasCredential) {
|
|
22515
22603
|
try {
|
|
22516
|
-
external_exports.object({ endpoint: external_exports.literal(DIAGNOSTIC_ENDPOINT), token: external_exports.string().min(32).max(512).regex(/^[A-Za-z0-9_-]+$/) }).strict().parse(JSON.parse((await privateRead(
|
|
22604
|
+
external_exports.object({ endpoint: external_exports.literal(DIAGNOSTIC_ENDPOINT), token: external_exports.string().min(32).max(512).regex(/^[A-Za-z0-9_-]+$/) }).strict().parse(JSON.parse((await privateRead(join11(profile, "config", "report-upload.json"), 16384)).toString()));
|
|
22517
22605
|
} catch {
|
|
22518
22606
|
throw Error("ENROLLMENT_REQUIRED");
|
|
22519
22607
|
}
|
|
22520
22608
|
} else await (typeof options === "function" ? enrollOpen : options.enrollOpen ?? enrollOpen)({ ...process.env, SBERPAY_CLI_HOME: profile });
|
|
22521
22609
|
}
|
|
22522
|
-
const configFile =
|
|
22610
|
+
const configFile = join11(privateDir2(join11(profile, "config")), "config.json");
|
|
22523
22611
|
let config2 = { stand: "prod", stands: {} };
|
|
22524
22612
|
try {
|
|
22525
22613
|
config2 = JSON.parse((await privateRead(configFile, 65536)).toString());
|
|
@@ -22532,45 +22620,46 @@ async function installLocked(source2, home, options) {
|
|
|
22532
22620
|
config2.stands[stand].merchantsUrl ??= "https://aiplatilka.ru/aim/aipay/gw/agent/api/v1";
|
|
22533
22621
|
}
|
|
22534
22622
|
await atomic(configFile, JSON.stringify(config2));
|
|
22535
|
-
const launcher =
|
|
22623
|
+
const launcher = join11(privateDir2(join11(root2, "bin")), "sberpay-cli-diagnostic.mjs");
|
|
22536
22624
|
const launcherText = `#!/usr/bin/env node
|
|
22537
22625
|
import {existsSync,readFileSync} from "node:fs";
|
|
22538
|
-
if(existsSync(${JSON.stringify(
|
|
22626
|
+
if(existsSync(${JSON.stringify(join11(root2, "install-pending.json"))})){console.log(JSON.stringify({status:"not_ready",code:"INSTALL_IN_PROGRESS"}));process.exit(4);}
|
|
22539
22627
|
try{const marker=JSON.parse(readFileSync(${JSON.stringify(markerPath)},"utf8"));if(marker.stateFormat!==2||marker.buildId!==${JSON.stringify(manifest.buildId)})throw Error();}catch{console.log(JSON.stringify({status:"not_ready",code:"SETUP_REQUIRED"}));process.exit(4);}
|
|
22540
22628
|
process.env.SBERPAY_CLI_HOME=${JSON.stringify(profile)};
|
|
22541
22629
|
process.env.SBERPAY_DIAGNOSTIC_CAPTURE="1";
|
|
22542
|
-
|
|
22630
|
+
process.env.SBERPAY_DIAGNOSTIC_LAUNCHER=${JSON.stringify(launcher)};
|
|
22631
|
+
await import(${JSON.stringify(pathToFileURL(join11(release, "bin", "sberpay-cli.mjs")).href)});
|
|
22543
22632
|
`;
|
|
22544
|
-
const original = await
|
|
22633
|
+
const original = await readFile3(join11(release, "skill", "sberpay", "SKILL.md"), "utf8");
|
|
22545
22634
|
const text = renderDiagnosticSkill(original, process.platform, launcher, process.execPath);
|
|
22546
22635
|
if (process.platform === "win32") privateDir2(skill);
|
|
22547
22636
|
else {
|
|
22548
|
-
await
|
|
22549
|
-
await
|
|
22637
|
+
await mkdir5(dirname6(skill), { recursive: true, mode: 448 });
|
|
22638
|
+
await mkdir5(skill, { mode: 448 }).catch((e) => {
|
|
22550
22639
|
if (e.code !== "EEXIST") throw e;
|
|
22551
22640
|
});
|
|
22552
22641
|
}
|
|
22553
|
-
const managed = [{ path: paymentModeFile, text: JSON.stringify(modeState), mode: 384 }, { path: launcher, text: launcherText, mode: 448 }, { path:
|
|
22642
|
+
const managed = [{ path: paymentModeFile, text: JSON.stringify(modeState), mode: 384 }, { path: launcher, text: launcherText, mode: 448 }, { path: join11(skill, "SKILL.md"), text, mode: 384 }];
|
|
22554
22643
|
for (const [path] of entries) {
|
|
22555
22644
|
if (!path.startsWith("skill/sberpay/") || path === "skill/sberpay/SKILL.md") continue;
|
|
22556
22645
|
const rel = path.slice("skill/sberpay/".length);
|
|
22557
22646
|
let cursor = skill;
|
|
22558
22647
|
for (const part of rel.split("/").slice(0, -1)) {
|
|
22559
|
-
cursor =
|
|
22560
|
-
await
|
|
22648
|
+
cursor = join11(cursor, part);
|
|
22649
|
+
await mkdir5(cursor, { mode: 448 }).catch((e) => {
|
|
22561
22650
|
if (e.code !== "EEXIST") throw e;
|
|
22562
22651
|
});
|
|
22563
|
-
const info = await
|
|
22652
|
+
const info = await lstat6(cursor);
|
|
22564
22653
|
if (!info.isDirectory() || info.isSymbolicLink()) throw Error("UNSAFE_SKILL_PATH");
|
|
22565
22654
|
}
|
|
22566
|
-
const target =
|
|
22655
|
+
const target = join11(skill, rel);
|
|
22567
22656
|
try {
|
|
22568
22657
|
await regular(target);
|
|
22569
|
-
const current = hash3(await
|
|
22658
|
+
const current = hash3(await readFile3(target, "utf8"));
|
|
22570
22659
|
let expected = prior?.skillFiles?.[rel];
|
|
22571
22660
|
if (!expected && prior?.buildId) {
|
|
22572
22661
|
try {
|
|
22573
|
-
expected = hash3(await
|
|
22662
|
+
expected = hash3(await readFile3(join11(releases, prior.buildId, "skill/sberpay", rel), "utf8"));
|
|
22574
22663
|
} catch {
|
|
22575
22664
|
}
|
|
22576
22665
|
}
|
|
@@ -22578,7 +22667,7 @@ await import(${JSON.stringify(pathToFileURL(join10(release, "bin", "sberpay-cli.
|
|
|
22578
22667
|
} catch (e) {
|
|
22579
22668
|
if (e.code !== "ENOENT") throw e;
|
|
22580
22669
|
}
|
|
22581
|
-
managed.push({ path: target, text: await
|
|
22670
|
+
managed.push({ path: target, text: await readFile3(join11(release, path), "utf8"), mode: 384 });
|
|
22582
22671
|
}
|
|
22583
22672
|
const skillFiles = skillFileHashes(skill, managed);
|
|
22584
22673
|
const marker = { buildId: manifest.buildId, stateFormat: 2, skillHash: hash3(text), skillFiles, launcher, profile };
|
|
@@ -22588,27 +22677,29 @@ await import(${JSON.stringify(pathToFileURL(join10(release, "bin", "sberpay-cli.
|
|
|
22588
22677
|
if (sender.status === "needs_activation") throw Error("SENDER_ACTIVATION_REQUIRED");
|
|
22589
22678
|
await durableWrite(markerPath, JSON.stringify(marker));
|
|
22590
22679
|
});
|
|
22591
|
-
|
|
22680
|
+
const claudeConfig = home === homedir3() && process.env.CLAUDE_CONFIG_DIR ? process.env.CLAUDE_CONFIG_DIR : join11(home, ".claude");
|
|
22681
|
+
const claudeHook = await updateClaudeHook(claudeConfig, claudeHookCommandFor([process.execPath, launcher])).catch(() => "skipped");
|
|
22682
|
+
return { status: "ready", profile: "diagnostic", buildId: manifest.buildId, launcher, skill, sender, claudeHook };
|
|
22592
22683
|
}
|
|
22593
22684
|
|
|
22594
22685
|
// scripts/diagnostics/npm-entry.mts
|
|
22595
22686
|
var source = dirname7(dirname7(fileURLToPath2(import.meta.url)));
|
|
22596
|
-
var root =
|
|
22687
|
+
var root = join12(homedir4(), ".local/share/sberpay-diagnostic");
|
|
22597
22688
|
try {
|
|
22598
22689
|
if (process.argv[2] === "setup") {
|
|
22599
22690
|
if (process.argv.slice(3).some((x) => x !== "--json")) throw Error("INVALID_SETUP_ARGUMENT");
|
|
22600
22691
|
const result = await installDiagnostic(source);
|
|
22601
22692
|
console.log(JSON.stringify(result));
|
|
22602
22693
|
} else {
|
|
22603
|
-
const manifest = JSON.parse(await
|
|
22694
|
+
const manifest = JSON.parse(await readFile4(join12(source, "manifest.json"), "utf8"));
|
|
22604
22695
|
let marker;
|
|
22605
22696
|
try {
|
|
22606
|
-
marker = JSON.parse(await
|
|
22697
|
+
marker = JSON.parse(await readFile4(join12(root, "installed.json"), "utf8"));
|
|
22607
22698
|
} catch {
|
|
22608
22699
|
throw Error("SETUP_REQUIRED");
|
|
22609
22700
|
}
|
|
22610
22701
|
if (marker.stateFormat !== 2 || marker.buildId !== manifest.buildId) throw Error("SETUP_REQUIRED");
|
|
22611
|
-
await import(pathToFileURL2(
|
|
22702
|
+
await import(pathToFileURL2(join12(root, "bin/sberpay-cli-diagnostic.mjs")).href);
|
|
22612
22703
|
}
|
|
22613
22704
|
} catch (e) {
|
|
22614
22705
|
console.log(JSON.stringify({ status: "not_ready", code: e.message, hint: "\u0412\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u0435 sberpay-cli-diagnostic setup --json; \u043F\u0440\u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u043E\u043C \u043E\u0442\u043A\u0430\u0437\u0435 \u0441\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u0435 \u043A\u043E\u0434 \u043E\u0448\u0438\u0431\u043A\u0438." }));
|