@bifos/nhncloud-cli 0.19.0 → 0.20.0
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/index.js
CHANGED
|
@@ -333,6 +333,69 @@ async function warnLegacyDeployTargets() {
|
|
|
333
333
|
)
|
|
334
334
|
);
|
|
335
335
|
}
|
|
336
|
+
async function readJsonState(filePath) {
|
|
337
|
+
let raw;
|
|
338
|
+
try {
|
|
339
|
+
raw = await (0, import_promises.readFile)(filePath, "utf-8");
|
|
340
|
+
} catch (err) {
|
|
341
|
+
const code = err.code;
|
|
342
|
+
if (code === "ENOENT") return { state: "missing" };
|
|
343
|
+
return { state: "unreadable", reason: `\uD30C\uC77C\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4 (${code ?? "UNKNOWN"})` };
|
|
344
|
+
}
|
|
345
|
+
try {
|
|
346
|
+
return { state: "ok", parsed: JSON.parse(raw) };
|
|
347
|
+
} catch {
|
|
348
|
+
return { state: "invalid", reason: "JSON \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4" };
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
async function inspectPermissions(filePath) {
|
|
352
|
+
try {
|
|
353
|
+
const { mode } = await (0, import_promises.stat)(filePath);
|
|
354
|
+
if (process.platform === "win32") return "unknown";
|
|
355
|
+
return (mode & 63) === 0 ? "ok" : "too-open";
|
|
356
|
+
} catch {
|
|
357
|
+
return void 0;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
function summarizeProfile(name, value) {
|
|
361
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
362
|
+
return { name, environment: "invalid", blocks: [] };
|
|
363
|
+
}
|
|
364
|
+
const profile = value;
|
|
365
|
+
const env = profile["environment"];
|
|
366
|
+
const environment = env === void 0 ? "real" : env === "gov" ? "gov" : "invalid";
|
|
367
|
+
const blocks = Object.keys(profile).filter((key) => key !== "environment").sort();
|
|
368
|
+
return { name, environment, blocks };
|
|
369
|
+
}
|
|
370
|
+
async function inspectCredentialsFile() {
|
|
371
|
+
const result = await readJsonState(CREDENTIALS_PATH);
|
|
372
|
+
const permissions = result.state === "missing" ? void 0 : await inspectPermissions(CREDENTIALS_PATH);
|
|
373
|
+
const base = { path: CREDENTIALS_PATH, ...permissions ? { permissions } : {}, profiles: [] };
|
|
374
|
+
if (result.state !== "ok") {
|
|
375
|
+
return { ...base, state: result.state, ...result.reason ? { reason: result.reason } : {} };
|
|
376
|
+
}
|
|
377
|
+
if (!isCredentials(result.parsed)) {
|
|
378
|
+
return { ...base, state: "invalid", reason: "version: 1 \uACFC profiles \uD544\uB4DC\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4" };
|
|
379
|
+
}
|
|
380
|
+
const profiles = Object.entries(result.parsed.profiles).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([name, value]) => summarizeProfile(name, value));
|
|
381
|
+
return { ...base, state: "ok", profiles };
|
|
382
|
+
}
|
|
383
|
+
async function inspectConfigFile() {
|
|
384
|
+
const result = await readJsonState(CONFIG_PATH);
|
|
385
|
+
const base = { path: CONFIG_PATH, defaultProfile: null };
|
|
386
|
+
if (result.state !== "ok") {
|
|
387
|
+
return { ...base, state: result.state, ...result.reason ? { reason: result.reason } : {} };
|
|
388
|
+
}
|
|
389
|
+
if (!isConfig(result.parsed)) {
|
|
390
|
+
return { ...base, state: "invalid", reason: "version: 1 \uC774 \uD544\uC694\uD569\uB2C8\uB2E4" };
|
|
391
|
+
}
|
|
392
|
+
const defaultProfile = result.parsed.defaultProfile;
|
|
393
|
+
return {
|
|
394
|
+
...base,
|
|
395
|
+
state: "ok",
|
|
396
|
+
defaultProfile: typeof defaultProfile === "string" && defaultProfile !== "" ? defaultProfile : null
|
|
397
|
+
};
|
|
398
|
+
}
|
|
336
399
|
|
|
337
400
|
// src/utils/terminal.ts
|
|
338
401
|
function sanitizeForTerminal(value) {
|
|
@@ -400,14 +463,97 @@ function parseNonNegativeIntegerOption(value, flag) {
|
|
|
400
463
|
|
|
401
464
|
// src/commands/commander-errors.ts
|
|
402
465
|
var import_commander = require("commander");
|
|
403
|
-
|
|
466
|
+
|
|
467
|
+
// src/commands/unknown-option-hint.ts
|
|
468
|
+
function normalizeName(name) {
|
|
469
|
+
return name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
470
|
+
}
|
|
471
|
+
function parseUnknownOptionName(message) {
|
|
472
|
+
return /unknown option '--([^'=]+)/.exec(message)?.[1];
|
|
473
|
+
}
|
|
474
|
+
function findReferencedArgument(optionName, commandPath2, argumentNames) {
|
|
475
|
+
const option = normalizeName(optionName);
|
|
476
|
+
const normalized = argumentNames.map(normalizeName);
|
|
477
|
+
const exact = normalized.indexOf(option);
|
|
478
|
+
if (exact !== -1) {
|
|
479
|
+
return argumentNames[exact];
|
|
480
|
+
}
|
|
481
|
+
const prefixed = argumentNames.filter((_, i) => normalized[i].startsWith(`${option}-`));
|
|
482
|
+
const candidates = new Set(prefixed.length === 1 ? prefixed : []);
|
|
483
|
+
const segments = commandPath2.slice(1).map(normalizeName);
|
|
484
|
+
argumentNames.forEach((name, i) => {
|
|
485
|
+
const otherArguments = normalized.filter((_, j) => j !== i);
|
|
486
|
+
const matched = segments.some(
|
|
487
|
+
(segment) => !otherArguments.includes(segment) && option === `${segment}-${normalized[i]}`
|
|
488
|
+
);
|
|
489
|
+
if (matched) {
|
|
490
|
+
candidates.add(name);
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
return candidates.size === 1 ? [...candidates][0] : void 0;
|
|
494
|
+
}
|
|
495
|
+
function formatArgument(argument) {
|
|
496
|
+
const name = argument.variadic ? `${argument.name}...` : argument.name;
|
|
497
|
+
return argument.required ? `<${name}>` : `[${name}]`;
|
|
498
|
+
}
|
|
499
|
+
function buildUnknownOptionHint(input) {
|
|
500
|
+
if (input.message.includes("(Did you mean")) {
|
|
501
|
+
return "";
|
|
502
|
+
}
|
|
503
|
+
const optionName = parseUnknownOptionName(input.message);
|
|
504
|
+
if (optionName === void 0) {
|
|
505
|
+
return "";
|
|
506
|
+
}
|
|
507
|
+
const referenced = findReferencedArgument(
|
|
508
|
+
optionName,
|
|
509
|
+
input.commandPath,
|
|
510
|
+
input.arguments.map((argument2) => argument2.name)
|
|
511
|
+
);
|
|
512
|
+
const argument = input.arguments.find((candidate) => candidate.name === referenced);
|
|
513
|
+
if (argument === void 0) {
|
|
514
|
+
return "";
|
|
515
|
+
}
|
|
516
|
+
return `\uC548\uB0B4: --${optionName} \uB294 \uC635\uC158\uC774 \uC544\uB2D9\uB2C8\uB2E4. \uC704\uCE58 \uC778\uC218 ${formatArgument(argument)} \uB85C \uC804\uB2EC\uD558\uC138\uC694.
|
|
517
|
+
\uC0AC\uC6A9\uBC95: ${input.commandPath.join(" ")} ${input.usage}
|
|
518
|
+
`;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// src/commands/commander-errors.ts
|
|
522
|
+
function writeUnknownOptionHint(command, error) {
|
|
523
|
+
const commandPath2 = [];
|
|
524
|
+
for (let current2 = command; current2 !== null; current2 = current2.parent) {
|
|
525
|
+
commandPath2.unshift(current2.name());
|
|
526
|
+
}
|
|
527
|
+
const hint = buildUnknownOptionHint({
|
|
528
|
+
message: error.message,
|
|
529
|
+
commandPath: commandPath2,
|
|
530
|
+
usage: command.usage(),
|
|
531
|
+
arguments: command.registeredArguments.map((argument) => ({
|
|
532
|
+
name: argument.name(),
|
|
533
|
+
required: argument.required,
|
|
534
|
+
variadic: argument.variadic
|
|
535
|
+
}))
|
|
536
|
+
});
|
|
537
|
+
if (hint === "") {
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
const writeErr = command.configureOutput().writeErr;
|
|
541
|
+
if (writeErr) {
|
|
542
|
+
writeErr(hint);
|
|
543
|
+
} else {
|
|
544
|
+
process.stderr.write(hint);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
function handleCommanderError(command, error) {
|
|
404
548
|
if (error.code === "commander.missingMandatoryOptionValue") {
|
|
405
549
|
error.exitCode = EXIT_PARAM_ERROR;
|
|
550
|
+
} else if (error.code === "commander.unknownOption") {
|
|
551
|
+
writeUnknownOptionHint(command, error);
|
|
406
552
|
}
|
|
407
553
|
throw error;
|
|
408
554
|
}
|
|
409
555
|
function configureCommanderExitCodes(root) {
|
|
410
|
-
root.exitOverride(
|
|
556
|
+
root.exitOverride((error) => handleCommanderError(root, error));
|
|
411
557
|
for (const command of root.commands) {
|
|
412
558
|
configureCommanderExitCodes(command);
|
|
413
559
|
}
|
|
@@ -422,7 +568,7 @@ function configureGlobalOptionsHelp(root) {
|
|
|
422
568
|
}
|
|
423
569
|
|
|
424
570
|
// src/version.ts
|
|
425
|
-
var CLI_VERSION = true ? "0.
|
|
571
|
+
var CLI_VERSION = true ? "0.20.0" : "0.0.0-dev";
|
|
426
572
|
|
|
427
573
|
// src/commands/configure.ts
|
|
428
574
|
var import_commander2 = require("commander");
|
|
@@ -2523,14 +2669,14 @@ function compareByCodePoint(left, right) {
|
|
|
2523
2669
|
return leftPoints.length - rightPoints.length;
|
|
2524
2670
|
}
|
|
2525
2671
|
function ensureRegularFile(filePath) {
|
|
2526
|
-
let
|
|
2672
|
+
let stat4;
|
|
2527
2673
|
try {
|
|
2528
|
-
|
|
2674
|
+
stat4 = (0, import_node_fs2.lstatSync)(filePath);
|
|
2529
2675
|
} catch (error) {
|
|
2530
2676
|
const reason = error instanceof Error ? error.message : String(error);
|
|
2531
2677
|
throw new NhnCloudCliError(`\uC2A4\uD0AC \uD30C\uC77C\uC744 \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${filePath} (${reason})`, EXIT_PARAM_ERROR);
|
|
2532
2678
|
}
|
|
2533
|
-
if (
|
|
2679
|
+
if (stat4.isSymbolicLink() || !stat4.isFile()) {
|
|
2534
2680
|
throw new NhnCloudCliError(`\uC2A4\uD0AC \uCF58\uD150\uCE20\uB294 \uC815\uADDC \uD30C\uC77C\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4: ${filePath}`, EXIT_PARAM_ERROR);
|
|
2535
2681
|
}
|
|
2536
2682
|
}
|
|
@@ -2547,21 +2693,21 @@ function collectReferenceFiles(referencesRoot, currentDir, files) {
|
|
|
2547
2693
|
}
|
|
2548
2694
|
for (const entry of entries) {
|
|
2549
2695
|
const entryPath = import_node_path4.default.join(currentDir, entry.name);
|
|
2550
|
-
let
|
|
2696
|
+
let stat4;
|
|
2551
2697
|
try {
|
|
2552
|
-
|
|
2698
|
+
stat4 = (0, import_node_fs2.lstatSync)(entryPath);
|
|
2553
2699
|
} catch (error) {
|
|
2554
2700
|
const reason = error instanceof Error ? error.message : String(error);
|
|
2555
2701
|
throw new NhnCloudCliError(`\uC2A4\uD0AC \uCF58\uD150\uCE20\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${entryPath} (${reason})`, EXIT_PARAM_ERROR);
|
|
2556
2702
|
}
|
|
2557
|
-
if (
|
|
2703
|
+
if (stat4.isSymbolicLink()) {
|
|
2558
2704
|
throw new NhnCloudCliError(`\uC2A4\uD0AC \uCF58\uD150\uCE20\uC5D0 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${entryPath}`, EXIT_PARAM_ERROR);
|
|
2559
2705
|
}
|
|
2560
|
-
if (
|
|
2706
|
+
if (stat4.isDirectory()) {
|
|
2561
2707
|
collectReferenceFiles(referencesRoot, entryPath, files);
|
|
2562
2708
|
continue;
|
|
2563
2709
|
}
|
|
2564
|
-
if (!
|
|
2710
|
+
if (!stat4.isFile()) {
|
|
2565
2711
|
throw new NhnCloudCliError(`\uC2A4\uD0AC \uCF58\uD150\uCE20\uB294 \uC815\uADDC \uD30C\uC77C \uB610\uB294 \uB514\uB809\uD130\uB9AC\uC5EC\uC57C \uD569\uB2C8\uB2E4: ${entryPath}`, EXIT_PARAM_ERROR);
|
|
2566
2712
|
}
|
|
2567
2713
|
files.push(`references/${import_node_path4.default.relative(referencesRoot, entryPath).split(import_node_path4.default.sep).join("/")}`);
|
|
@@ -2609,12 +2755,24 @@ function calculateSkillContentDigest(skillRoot) {
|
|
|
2609
2755
|
var PACKAGE_NAME3 = "@bifos/nhncloud-cli";
|
|
2610
2756
|
var SKILL_NAME2 = "nhncloud-cli";
|
|
2611
2757
|
var DIGEST_HEX_PATTERN = /^[0-9a-f]{64}$/;
|
|
2612
|
-
var
|
|
2758
|
+
var SKILL_AGENTS = ["claude", "codex"];
|
|
2759
|
+
var SKILL_AGENT_NAMES = { claude: "Claude Code", codex: "Codex" };
|
|
2760
|
+
var STATUS_PRIORITY = [
|
|
2761
|
+
"corrupt",
|
|
2762
|
+
"modified",
|
|
2763
|
+
"unmanaged",
|
|
2764
|
+
"broken",
|
|
2765
|
+
"outdated",
|
|
2766
|
+
"missing",
|
|
2767
|
+
"current"
|
|
2768
|
+
];
|
|
2769
|
+
var PROTECTED_STATUSES = ["unmanaged", "modified", "corrupt"];
|
|
2770
|
+
var defaultOperations = { rename: import_promises3.rename, rm: import_promises3.rm };
|
|
2613
2771
|
function sourcePath(context) {
|
|
2614
2772
|
return import_node_path5.default.join(context.packageRoot, "skills", SKILL_NAME2);
|
|
2615
2773
|
}
|
|
2616
|
-
function destinationPath(context) {
|
|
2617
|
-
return import_node_path5.default.join(context.homeDir, ".claude", "skills", SKILL_NAME2);
|
|
2774
|
+
function destinationPath(context, agent) {
|
|
2775
|
+
return agent === "claude" ? import_node_path5.default.join(context.homeDir, ".claude", "skills", SKILL_NAME2) : import_node_path5.default.join(context.homeDir, ".agents", "skills", SKILL_NAME2);
|
|
2618
2776
|
}
|
|
2619
2777
|
function resolveLinkTarget(linkPath, rawTarget) {
|
|
2620
2778
|
return import_node_path5.default.isAbsolute(rawTarget) ? import_node_path5.default.normalize(rawTarget) : import_node_path5.default.resolve(import_node_path5.default.dirname(linkPath), rawTarget);
|
|
@@ -2725,16 +2883,74 @@ async function inspectRepository(targetPath, expected) {
|
|
|
2725
2883
|
}
|
|
2726
2884
|
return { status: "valid", installedVersion: manifest.packageVersion };
|
|
2727
2885
|
}
|
|
2728
|
-
function statusBase(context) {
|
|
2886
|
+
function statusBase(context, agent) {
|
|
2729
2887
|
return {
|
|
2730
2888
|
schemaVersion: 1,
|
|
2731
|
-
destination: destinationPath(context),
|
|
2889
|
+
destination: destinationPath(context, agent),
|
|
2732
2890
|
source: sourcePath(context),
|
|
2733
2891
|
currentVersion: context.currentVersion
|
|
2734
2892
|
};
|
|
2735
2893
|
}
|
|
2736
|
-
async function
|
|
2737
|
-
const
|
|
2894
|
+
async function managedRepositoryStatus(context, base, linkTarget, repositoryLocation, isExpectedPath) {
|
|
2895
|
+
const repositoryName = parseRepositoryName(repositoryLocation);
|
|
2896
|
+
if (!repositoryName) {
|
|
2897
|
+
return { ...base, status: "corrupt", linkTarget, managed: true };
|
|
2898
|
+
}
|
|
2899
|
+
const repository = await inspectRepository(repositoryLocation, repositoryName);
|
|
2900
|
+
if (repository.status === "modified" || repository.status === "corrupt") {
|
|
2901
|
+
return {
|
|
2902
|
+
...base,
|
|
2903
|
+
status: repository.status,
|
|
2904
|
+
installedVersion: repository.installedVersion ?? repositoryName.version,
|
|
2905
|
+
linkTarget,
|
|
2906
|
+
managed: true
|
|
2907
|
+
};
|
|
2908
|
+
}
|
|
2909
|
+
if (repository.status === "missing") {
|
|
2910
|
+
return {
|
|
2911
|
+
...base,
|
|
2912
|
+
status: "broken",
|
|
2913
|
+
installedVersion: repositoryName.version,
|
|
2914
|
+
linkTarget,
|
|
2915
|
+
managed: true
|
|
2916
|
+
};
|
|
2917
|
+
}
|
|
2918
|
+
const currentDigest = calculateSkillContentDigest(base.source);
|
|
2919
|
+
const isCurrent = repositoryName.version === context.currentVersion && repositoryName.digest === currentDigest && await isExpectedPath(repositoryPath(context, currentDigest));
|
|
2920
|
+
return {
|
|
2921
|
+
...base,
|
|
2922
|
+
status: isCurrent ? "current" : "outdated",
|
|
2923
|
+
installedVersion: repository.installedVersion,
|
|
2924
|
+
linkTarget,
|
|
2925
|
+
managed: true
|
|
2926
|
+
};
|
|
2927
|
+
}
|
|
2928
|
+
async function optionalRealpath(targetPath) {
|
|
2929
|
+
try {
|
|
2930
|
+
return await (0, import_promises3.realpath)(targetPath);
|
|
2931
|
+
} catch (error) {
|
|
2932
|
+
if (isNodeError(error, "ENOENT")) {
|
|
2933
|
+
return void 0;
|
|
2934
|
+
}
|
|
2935
|
+
throw managerError(`\uC2A4\uD0AC \uACBD\uB85C\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${targetPath}`, error);
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
async function inspectIndirectManagedLink(context, base, linkTarget) {
|
|
2939
|
+
const realRoot = await optionalRealpath(repositoryRoot(context));
|
|
2940
|
+
if (!realRoot) {
|
|
2941
|
+
return void 0;
|
|
2942
|
+
}
|
|
2943
|
+
const realTarget = await optionalRealpath(linkTarget);
|
|
2944
|
+
if (!realTarget || import_node_path5.default.dirname(realTarget) !== realRoot) {
|
|
2945
|
+
return void 0;
|
|
2946
|
+
}
|
|
2947
|
+
return managedRepositoryStatus(context, base, linkTarget, realTarget, async (expectedPath) => {
|
|
2948
|
+
const realExpected = await optionalRealpath(expectedPath);
|
|
2949
|
+
return realExpected !== void 0 && realExpected === realTarget;
|
|
2950
|
+
});
|
|
2951
|
+
}
|
|
2952
|
+
async function inspectAgentSkill(context, agent) {
|
|
2953
|
+
const base = statusBase(context, agent);
|
|
2738
2954
|
const destinationStat = await optionalLstat(base.destination);
|
|
2739
2955
|
if (!destinationStat) {
|
|
2740
2956
|
return { ...base, status: "missing", managed: false };
|
|
@@ -2767,38 +2983,17 @@ async function inspectSkill(context) {
|
|
|
2767
2983
|
};
|
|
2768
2984
|
}
|
|
2769
2985
|
if (isManagedRepositoryLocation(context, linkTarget)) {
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
const repository = await inspectRepository(linkTarget, repositoryName);
|
|
2774
|
-
if (repository.status === "modified" || repository.status === "corrupt") {
|
|
2775
|
-
return {
|
|
2776
|
-
...base,
|
|
2777
|
-
status: repository.status,
|
|
2778
|
-
installedVersion: repository.installedVersion ?? repositoryName.version,
|
|
2779
|
-
linkTarget,
|
|
2780
|
-
managed: true
|
|
2781
|
-
};
|
|
2782
|
-
}
|
|
2783
|
-
if (repository.status === "missing") {
|
|
2784
|
-
return {
|
|
2785
|
-
...base,
|
|
2786
|
-
status: "broken",
|
|
2787
|
-
installedVersion: repositoryName.version,
|
|
2788
|
-
linkTarget,
|
|
2789
|
-
managed: true
|
|
2790
|
-
};
|
|
2791
|
-
}
|
|
2792
|
-
const currentDigest = calculateSkillContentDigest(base.source);
|
|
2793
|
-
const expectedPath = repositoryPath(context, currentDigest);
|
|
2794
|
-
const isCurrent = repositoryName.version === context.currentVersion && repositoryName.digest === currentDigest && import_node_path5.default.resolve(linkTarget) === import_node_path5.default.resolve(expectedPath);
|
|
2795
|
-
return {
|
|
2796
|
-
...base,
|
|
2797
|
-
status: isCurrent ? "current" : "outdated",
|
|
2798
|
-
installedVersion: repository.installedVersion,
|
|
2986
|
+
return managedRepositoryStatus(
|
|
2987
|
+
context,
|
|
2988
|
+
base,
|
|
2799
2989
|
linkTarget,
|
|
2800
|
-
|
|
2801
|
-
|
|
2990
|
+
linkTarget,
|
|
2991
|
+
async (expectedPath) => import_node_path5.default.resolve(linkTarget) === import_node_path5.default.resolve(expectedPath)
|
|
2992
|
+
);
|
|
2993
|
+
}
|
|
2994
|
+
const indirect = await inspectIndirectManagedLink(context, base, linkTarget);
|
|
2995
|
+
if (indirect) {
|
|
2996
|
+
return indirect;
|
|
2802
2997
|
}
|
|
2803
2998
|
const legacyPackage = targetStat.isDirectory() ? await readLegacyPackageMetadata(linkTarget) : void 0;
|
|
2804
2999
|
if (legacyPackage) {
|
|
@@ -2812,6 +3007,14 @@ async function inspectSkill(context) {
|
|
|
2812
3007
|
}
|
|
2813
3008
|
return { ...base, status: "unmanaged", linkTarget, managed: false };
|
|
2814
3009
|
}
|
|
3010
|
+
function aggregateStatus(statuses) {
|
|
3011
|
+
return STATUS_PRIORITY.find((token) => statuses.some((status) => status.status === token)) ?? "current";
|
|
3012
|
+
}
|
|
3013
|
+
async function inspectSkill(context) {
|
|
3014
|
+
const claude = await inspectAgentSkill(context, "claude");
|
|
3015
|
+
const codex = await inspectAgentSkill(context, "codex");
|
|
3016
|
+
return { ...claude, status: aggregateStatus([claude, codex]), agents: { claude, codex } };
|
|
3017
|
+
}
|
|
2815
3018
|
function utcBackupSuffix() {
|
|
2816
3019
|
return `${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}-${(0, import_node_crypto3.randomUUID)()}`;
|
|
2817
3020
|
}
|
|
@@ -2908,35 +3111,123 @@ async function prepareRepository(context, force, operations) {
|
|
|
2908
3111
|
await (0, import_promises3.rm)(staging, { recursive: true, force: true });
|
|
2909
3112
|
}
|
|
2910
3113
|
}
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
const
|
|
2916
|
-
const
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
3114
|
+
function temporaryLinkPath(destination) {
|
|
3115
|
+
return import_node_path5.default.join(import_node_path5.default.dirname(destination), `.${SKILL_NAME2}.link-${(0, import_node_crypto3.randomUUID)()}`);
|
|
3116
|
+
}
|
|
3117
|
+
async function planLinkSwitches(context, previous) {
|
|
3118
|
+
const switches = [];
|
|
3119
|
+
for (const agent of SKILL_AGENTS) {
|
|
3120
|
+
const agentStatus = previous.agents[agent];
|
|
3121
|
+
if (agentStatus.status === "current") {
|
|
3122
|
+
continue;
|
|
3123
|
+
}
|
|
3124
|
+
const destination = destinationPath(context, agent);
|
|
3125
|
+
const parent = import_node_path5.default.dirname(destination);
|
|
3126
|
+
await (0, import_promises3.mkdir)(parent, { recursive: true });
|
|
3127
|
+
const resolvedDestination = import_node_path5.default.join(await (0, import_promises3.realpath)(parent), import_node_path5.default.basename(destination));
|
|
3128
|
+
const sameTarget = switches.find((entry) => entry.resolvedDestination === resolvedDestination);
|
|
3129
|
+
if (sameTarget) {
|
|
3130
|
+
sameTarget.agents.push(agent);
|
|
3131
|
+
continue;
|
|
3132
|
+
}
|
|
3133
|
+
let previousRawTarget;
|
|
3134
|
+
if (agentStatus.status !== "missing" && agentStatus.status !== "unmanaged") {
|
|
2925
3135
|
try {
|
|
2926
|
-
await
|
|
3136
|
+
previousRawTarget = await (0, import_promises3.readlink)(destination);
|
|
2927
3137
|
} catch (error) {
|
|
2928
|
-
|
|
3138
|
+
throw managerError(`\uC2A4\uD0AC \uB9C1\uD06C\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${destination}`, error);
|
|
2929
3139
|
}
|
|
2930
|
-
return backupPaths;
|
|
2931
3140
|
}
|
|
3141
|
+
switches.push({
|
|
3142
|
+
agents: [agent],
|
|
3143
|
+
destination,
|
|
3144
|
+
resolvedDestination,
|
|
3145
|
+
previous: agentStatus,
|
|
3146
|
+
previousRawTarget,
|
|
3147
|
+
temporaryLink: temporaryLinkPath(destination),
|
|
3148
|
+
activated: false
|
|
3149
|
+
});
|
|
3150
|
+
}
|
|
3151
|
+
return switches;
|
|
3152
|
+
}
|
|
3153
|
+
async function rollbackLinkSwitches(switches, operations, temporaryLinks) {
|
|
3154
|
+
const failed = [];
|
|
3155
|
+
const preservedBackups = [];
|
|
3156
|
+
const removeEntry = operations.rm ?? defaultOperations.rm;
|
|
3157
|
+
let firstError;
|
|
3158
|
+
for (const entry of [...switches].reverse()) {
|
|
2932
3159
|
try {
|
|
2933
|
-
|
|
3160
|
+
if (entry.activated && entry.backup) {
|
|
3161
|
+
await removeEntry(entry.destination, { force: true });
|
|
3162
|
+
await operations.rename(entry.backup, entry.destination);
|
|
3163
|
+
} else if (entry.activated && entry.previousRawTarget !== void 0) {
|
|
3164
|
+
const restoreLink = temporaryLinkPath(entry.destination);
|
|
3165
|
+
temporaryLinks.push(restoreLink);
|
|
3166
|
+
await (0, import_promises3.symlink)(entry.previousRawTarget, restoreLink);
|
|
3167
|
+
await operations.rename(restoreLink, entry.destination);
|
|
3168
|
+
} else if (entry.activated && entry.previous.status === "missing") {
|
|
3169
|
+
await removeEntry(entry.destination, { force: true });
|
|
3170
|
+
} else if (!entry.activated && entry.backup) {
|
|
3171
|
+
await operations.rename(entry.backup, entry.destination);
|
|
3172
|
+
}
|
|
2934
3173
|
} catch (error) {
|
|
2935
|
-
|
|
3174
|
+
failed.push(entry.destination);
|
|
3175
|
+
if (entry.backup) {
|
|
3176
|
+
preservedBackups.push(entry.backup);
|
|
3177
|
+
}
|
|
3178
|
+
firstError ??= error;
|
|
2936
3179
|
}
|
|
2937
|
-
|
|
3180
|
+
}
|
|
3181
|
+
return { failed, preservedBackups, firstError };
|
|
3182
|
+
}
|
|
3183
|
+
async function switchActiveLinks(context, repository, previous, operations) {
|
|
3184
|
+
const switches = await planLinkSwitches(context, previous);
|
|
3185
|
+
const temporaryLinks = switches.map((entry) => entry.temporaryLink);
|
|
3186
|
+
const backupPaths = [];
|
|
3187
|
+
try {
|
|
3188
|
+
let failure;
|
|
3189
|
+
let failedAfterVerification = false;
|
|
3190
|
+
try {
|
|
3191
|
+
for (const entry of switches) {
|
|
3192
|
+
await (0, import_promises3.symlink)(repository, entry.temporaryLink);
|
|
3193
|
+
}
|
|
3194
|
+
for (const entry of switches) {
|
|
3195
|
+
if (entry.previous.status === "unmanaged") {
|
|
3196
|
+
entry.backup = await backupPath(entry.destination, operations);
|
|
3197
|
+
backupPaths.push(entry.backup);
|
|
3198
|
+
}
|
|
3199
|
+
await operations.rename(entry.temporaryLink, entry.destination);
|
|
3200
|
+
entry.activated = true;
|
|
3201
|
+
}
|
|
3202
|
+
const status = await inspectSkill(context);
|
|
3203
|
+
if (status.status === "current") {
|
|
3204
|
+
return { backupPaths, status };
|
|
3205
|
+
}
|
|
3206
|
+
failure = managerError(`\uC2A4\uD0AC \uC124\uCE58 \uD6C4 \uC0C1\uD0DC\uAC00 current\uAC00 \uC544\uB2D9\uB2C8\uB2E4: ${status.status}`);
|
|
3207
|
+
failedAfterVerification = true;
|
|
3208
|
+
} catch (error) {
|
|
3209
|
+
failure = error;
|
|
3210
|
+
}
|
|
3211
|
+
const rollback = await rollbackLinkSwitches(switches, operations, temporaryLinks);
|
|
3212
|
+
if (rollback.failed.length > 0) {
|
|
3213
|
+
throw managerError(
|
|
3214
|
+
`\uC2A4\uD0AC \uC804\uD658\uC5D0 \uC2E4\uD328\uD588\uACE0 \uC77C\uBD80 \uACBD\uB85C\uB97C \uB418\uB3CC\uB9AC\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${rollback.failed.join(", ")}; \uBCF4\uC874\uD55C \uBC31\uC5C5: ${rollback.preservedBackups.join(", ") || "\uC5C6\uC74C"}; \uC804\uD658 \uC624\uB958: ${toReason(failure)}`,
|
|
3215
|
+
rollback.firstError
|
|
3216
|
+
);
|
|
3217
|
+
}
|
|
3218
|
+
if (failedAfterVerification) {
|
|
3219
|
+
throw failure;
|
|
3220
|
+
}
|
|
3221
|
+
const changed = switches.filter((entry) => entry.activated || entry.backup !== void 0);
|
|
3222
|
+
if (changed.length === 0) {
|
|
3223
|
+
throw managerError("\uC2A4\uD0AC \uC804\uD658\uC744 \uC2DC\uC791\uD558\uC9C0 \uBABB\uD574 \uC5B4\uB5A4 \uACBD\uB85C\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4", failure);
|
|
3224
|
+
}
|
|
3225
|
+
throw managerError(
|
|
3226
|
+
`\uC2A4\uD0AC \uC804\uD658\uC5D0 \uC2E4\uD328\uD574 \uBC14\uAFBC \uACBD\uB85C\uB97C \uC774\uC804 \uC0C1\uD0DC\uB85C \uB418\uB3CC\uB838\uC2B5\uB2C8\uB2E4: ${changed.map((entry) => entry.destination).join(", ")}`,
|
|
3227
|
+
failure
|
|
3228
|
+
);
|
|
2938
3229
|
} finally {
|
|
2939
|
-
await (0, import_promises3.rm)(
|
|
3230
|
+
await Promise.all(temporaryLinks.map((link) => (0, import_promises3.rm)(link, { force: true })));
|
|
2940
3231
|
}
|
|
2941
3232
|
}
|
|
2942
3233
|
function installAction(status) {
|
|
@@ -2971,23 +3262,26 @@ async function installSkillInternal(context, options = {}, operations = defaultO
|
|
|
2971
3262
|
backupPaths: []
|
|
2972
3263
|
};
|
|
2973
3264
|
}
|
|
2974
|
-
if (
|
|
2975
|
-
|
|
3265
|
+
if (!force) {
|
|
3266
|
+
for (const agent of SKILL_AGENTS) {
|
|
3267
|
+
const agentStatus = previousStatus.agents[agent];
|
|
3268
|
+
if (PROTECTED_STATUSES.includes(agentStatus.status)) {
|
|
3269
|
+
throw managerError(
|
|
3270
|
+
`${SKILL_AGENT_NAMES[agent]} \uC2A4\uD0AC \uC0C1\uD0DC\uAC00 ${agentStatus.status}\uC785\uB2C8\uB2E4. --force\uB85C \uBC31\uC5C5 \uD6C4 \uAD50\uCCB4\uD558\uC138\uC694: ${agentStatus.destination}`
|
|
3271
|
+
);
|
|
3272
|
+
}
|
|
3273
|
+
}
|
|
2976
3274
|
}
|
|
2977
3275
|
const prepared = await prepareRepository(context, force, operations);
|
|
2978
|
-
const
|
|
2979
|
-
const status = await inspectSkill(context);
|
|
2980
|
-
if (status.status !== "current") {
|
|
2981
|
-
throw managerError(`\uC2A4\uD0AC \uC124\uCE58 \uD6C4 \uC0C1\uD0DC\uAC00 current\uAC00 \uC544\uB2D9\uB2C8\uB2E4: ${status.status}`);
|
|
2982
|
-
}
|
|
3276
|
+
const switched = await switchActiveLinks(context, prepared.repository, previousStatus, operations);
|
|
2983
3277
|
return {
|
|
2984
3278
|
schemaVersion: 1,
|
|
2985
3279
|
action: installAction(previousStatus.status),
|
|
2986
3280
|
changed: true,
|
|
2987
3281
|
previousStatus,
|
|
2988
|
-
status,
|
|
3282
|
+
status: switched.status,
|
|
2989
3283
|
repositoryPath: prepared.repository,
|
|
2990
|
-
backupPaths: [...prepared.backupPaths, ...
|
|
3284
|
+
backupPaths: [...prepared.backupPaths, ...switched.backupPaths]
|
|
2991
3285
|
};
|
|
2992
3286
|
}
|
|
2993
3287
|
async function installSkill(context, options = {}, operations = defaultOperations) {
|
|
@@ -3000,73 +3294,185 @@ async function installSkill(context, options = {}, operations = defaultOperation
|
|
|
3000
3294
|
throw managerError("\uC2A4\uD0AC\uC744 \uC124\uCE58\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.", error);
|
|
3001
3295
|
}
|
|
3002
3296
|
}
|
|
3297
|
+
async function tryRestoreCandidate(candidate, destination, operations) {
|
|
3298
|
+
try {
|
|
3299
|
+
if (await optionalLstat(destination)) {
|
|
3300
|
+
return { restored: false, preserved: candidate };
|
|
3301
|
+
}
|
|
3302
|
+
await operations.rename(candidate, destination);
|
|
3303
|
+
return { restored: true };
|
|
3304
|
+
} catch (error) {
|
|
3305
|
+
return { restored: false, error, preserved: candidate };
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3003
3308
|
async function restoreUninstallCandidate(candidate, destination, operations, originalError) {
|
|
3004
|
-
|
|
3309
|
+
const result = await tryRestoreCandidate(candidate, destination, operations);
|
|
3310
|
+
if (result.restored) {
|
|
3311
|
+
throw managerError(`\uD65C\uC131 \uC2A4\uD0AC \uB9C1\uD06C\uB97C \uC81C\uAC70\uD558\uC9C0 \uC54A\uACE0 \uC6D0\uB798 \uC704\uCE58\uB85C \uBCF5\uC6D0\uD588\uC2B5\uB2C8\uB2E4: ${destination}`, originalError);
|
|
3312
|
+
}
|
|
3313
|
+
if (result.error === void 0) {
|
|
3005
3314
|
throw managerError(
|
|
3006
3315
|
`\uD65C\uC131 \uC2A4\uD0AC \uACBD\uB85C\uAC00 \uB3D9\uC2DC\uC5D0 \uBCC0\uACBD\uB418\uC5B4 \uC81C\uAC70\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC774\uB3D9\uB41C \uD56D\uBAA9\uC744 \uBCF4\uC874\uD588\uC2B5\uB2C8\uB2E4: ${candidate}`,
|
|
3007
3316
|
originalError
|
|
3008
3317
|
);
|
|
3009
3318
|
}
|
|
3319
|
+
throw managerError(
|
|
3320
|
+
`\uD65C\uC131 \uC2A4\uD0AC \uB9C1\uD06C\uB97C \uC81C\uAC70\uD558\uC9C0 \uBABB\uD588\uACE0 \uC6D0\uB798 \uC704\uCE58\uB85C \uBCF5\uC6D0\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uC774\uB3D9\uB41C \uD56D\uBAA9: ${candidate}; \uC81C\uAC70 \uC624\uB958: ${toReason(originalError)}`,
|
|
3321
|
+
result.error
|
|
3322
|
+
);
|
|
3323
|
+
}
|
|
3324
|
+
async function tryRestoreRemovedLink(destination, rawTarget, operations) {
|
|
3325
|
+
const restoreLink = temporaryLinkPath(destination);
|
|
3010
3326
|
try {
|
|
3011
|
-
await
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3327
|
+
if (await optionalLstat(destination)) {
|
|
3328
|
+
return { restored: false };
|
|
3329
|
+
}
|
|
3330
|
+
await (0, import_promises3.symlink)(rawTarget, restoreLink);
|
|
3331
|
+
await operations.rename(restoreLink, destination);
|
|
3332
|
+
return { restored: true };
|
|
3333
|
+
} catch (error) {
|
|
3334
|
+
return { restored: false, error };
|
|
3335
|
+
} finally {
|
|
3336
|
+
await (0, import_promises3.rm)(restoreLink, { force: true });
|
|
3017
3337
|
}
|
|
3018
|
-
throw managerError(`\uD65C\uC131 \uC2A4\uD0AC \uB9C1\uD06C\uB97C \uC81C\uAC70\uD558\uC9C0 \uC54A\uACE0 \uC6D0\uB798 \uC704\uCE58\uB85C \uBCF5\uC6D0\uD588\uC2B5\uB2C8\uB2E4: ${destination}`, originalError);
|
|
3019
3338
|
}
|
|
3020
|
-
async function
|
|
3021
|
-
const
|
|
3022
|
-
const
|
|
3023
|
-
|
|
3024
|
-
|
|
3339
|
+
async function planUninstallTargets(context) {
|
|
3340
|
+
const statuses = [];
|
|
3341
|
+
for (const agent of SKILL_AGENTS) {
|
|
3342
|
+
const status = await inspectAgentSkill(context, agent);
|
|
3343
|
+
if (status.status !== "missing" && (!status.managed || !status.linkTarget)) {
|
|
3344
|
+
throw managerError(`\uAD00\uB9AC\uB418\uC9C0 \uC54A\uC740 \uC2A4\uD0AC \uD56D\uBAA9\uC774\uBBC0\uB85C \uC5B4\uB290 \uACBD\uB85C\uB3C4 \uC81C\uAC70\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4: ${status.destination}`);
|
|
3345
|
+
}
|
|
3346
|
+
statuses.push({ agent, status });
|
|
3347
|
+
}
|
|
3348
|
+
const targets = [];
|
|
3349
|
+
for (const { agent, status } of statuses) {
|
|
3350
|
+
if (status.status === "missing" || !status.linkTarget) {
|
|
3351
|
+
continue;
|
|
3352
|
+
}
|
|
3353
|
+
const realParent = await optionalRealpath(import_node_path5.default.dirname(status.destination));
|
|
3354
|
+
if (!realParent) {
|
|
3355
|
+
continue;
|
|
3356
|
+
}
|
|
3357
|
+
const resolvedDestination = import_node_path5.default.join(realParent, import_node_path5.default.basename(status.destination));
|
|
3358
|
+
const sameTarget = targets.find((entry) => entry.resolvedDestination === resolvedDestination);
|
|
3359
|
+
if (sameTarget) {
|
|
3360
|
+
sameTarget.agents.push(agent);
|
|
3361
|
+
continue;
|
|
3362
|
+
}
|
|
3363
|
+
targets.push({
|
|
3364
|
+
agents: [agent],
|
|
3365
|
+
destination: status.destination,
|
|
3366
|
+
resolvedDestination,
|
|
3367
|
+
linkTarget: status.linkTarget
|
|
3368
|
+
});
|
|
3369
|
+
}
|
|
3370
|
+
return targets;
|
|
3371
|
+
}
|
|
3372
|
+
function uninstallRollbackError(results, originalError, handledLabel) {
|
|
3373
|
+
const failed = results.filter(({ result }) => !result.restored);
|
|
3374
|
+
if (failed.length === 0) {
|
|
3375
|
+
return managerError(
|
|
3376
|
+
`\uC2A4\uD0AC \uC81C\uAC70\uC5D0 \uC2E4\uD328\uD574 ${handledLabel}\uB97C \uC774\uC804 \uC0C1\uD0DC\uB85C \uB418\uB3CC\uB838\uC2B5\uB2C8\uB2E4: ${results.map(({ destination }) => destination).join(", ")}`,
|
|
3377
|
+
originalError
|
|
3378
|
+
);
|
|
3025
3379
|
}
|
|
3026
|
-
|
|
3027
|
-
|
|
3380
|
+
const failedText = failed.map(
|
|
3381
|
+
({ destination, result }) => result.preserved ? `${destination} (\uC774\uB3D9\uB41C \uD56D\uBAA9: ${result.preserved})` : destination
|
|
3382
|
+
).join(", ");
|
|
3383
|
+
return managerError(
|
|
3384
|
+
`\uC2A4\uD0AC \uC81C\uAC70\uC5D0 \uC2E4\uD328\uD588\uACE0 \uC77C\uBD80 \uACBD\uB85C\uB97C \uB418\uB3CC\uB9AC\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${failedText}; \uC81C\uAC70 \uC624\uB958: ${toReason(originalError)}`,
|
|
3385
|
+
failed.find(({ result }) => result.error !== void 0)?.result.error
|
|
3386
|
+
);
|
|
3387
|
+
}
|
|
3388
|
+
async function rollbackMovedCandidates(moved, operations, originalError) {
|
|
3389
|
+
const results = [];
|
|
3390
|
+
for (const target of [...moved].reverse()) {
|
|
3391
|
+
results.push({
|
|
3392
|
+
destination: target.destination,
|
|
3393
|
+
result: await tryRestoreCandidate(target.candidate, target.destination, operations)
|
|
3394
|
+
});
|
|
3028
3395
|
}
|
|
3396
|
+
throw uninstallRollbackError(results, originalError, "\uC62E\uAE34 \uACBD\uB85C");
|
|
3397
|
+
}
|
|
3398
|
+
async function moveUninstallCandidate(target, moved, operations) {
|
|
3399
|
+
const { destination } = target;
|
|
3029
3400
|
const candidate = import_node_path5.default.join(import_node_path5.default.dirname(destination), `.${SKILL_NAME2}.uninstall-${(0, import_node_crypto3.randomUUID)()}`);
|
|
3030
3401
|
try {
|
|
3031
3402
|
await operations.rename(destination, candidate);
|
|
3032
3403
|
} catch (error) {
|
|
3033
3404
|
if (isNodeError(error, "ENOENT")) {
|
|
3034
|
-
return
|
|
3405
|
+
return void 0;
|
|
3406
|
+
}
|
|
3407
|
+
const moveError = managerError(`\uD65C\uC131 \uC2A4\uD0AC \uB9C1\uD06C\uB97C \uC81C\uAC70\uC6A9 \uC784\uC2DC \uACBD\uB85C\uB85C \uC774\uB3D9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${destination}`, error);
|
|
3408
|
+
if (moved.length === 0) {
|
|
3409
|
+
throw moveError;
|
|
3035
3410
|
}
|
|
3036
|
-
|
|
3411
|
+
return await rollbackMovedCandidates(moved, operations, moveError);
|
|
3037
3412
|
}
|
|
3038
|
-
let
|
|
3413
|
+
let rawTarget;
|
|
3414
|
+
let verificationError;
|
|
3039
3415
|
try {
|
|
3040
3416
|
const candidateStat = await (0, import_promises3.lstat)(candidate);
|
|
3041
3417
|
if (!candidateStat.isSymbolicLink()) {
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
new Error("\uAC80\uC0AC \uD6C4 \uD65C\uC131 \
|
|
3047
|
-
|
|
3418
|
+
verificationError = new Error("\uAC80\uC0AC \uD6C4 \uD65C\uC131 \uACBD\uB85C\uAC00 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uAC00 \uC544\uB2CC \uD56D\uBAA9\uC73C\uB85C \uBCC0\uACBD\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
|
|
3419
|
+
} else {
|
|
3420
|
+
rawTarget = await (0, import_promises3.readlink)(candidate);
|
|
3421
|
+
if (resolveLinkTarget(destination, rawTarget) !== target.linkTarget) {
|
|
3422
|
+
verificationError = new Error("\uAC80\uC0AC \uD6C4 \uD65C\uC131 \uC2A4\uD0AC \uB9C1\uD06C \uB300\uC0C1\uC774 \uBCC0\uACBD\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
|
|
3423
|
+
}
|
|
3048
3424
|
}
|
|
3049
|
-
candidateTarget = resolveLinkTarget(destination, await (0, import_promises3.readlink)(candidate));
|
|
3050
3425
|
} catch (error) {
|
|
3051
|
-
|
|
3052
|
-
|
|
3426
|
+
verificationError = error;
|
|
3427
|
+
}
|
|
3428
|
+
if (verificationError !== void 0 || rawTarget === void 0) {
|
|
3429
|
+
if (moved.length === 0) {
|
|
3430
|
+
return await restoreUninstallCandidate(candidate, destination, operations, verificationError);
|
|
3053
3431
|
}
|
|
3054
|
-
return await
|
|
3432
|
+
return await rollbackMovedCandidates([...moved, { destination, candidate }], operations, verificationError);
|
|
3055
3433
|
}
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3434
|
+
return { ...target, candidate, rawTarget };
|
|
3435
|
+
}
|
|
3436
|
+
async function removeUninstallCandidates(moved, operations) {
|
|
3437
|
+
const removeEntry = operations.rm ?? defaultOperations.rm;
|
|
3438
|
+
for (const [index, target] of moved.entries()) {
|
|
3439
|
+
try {
|
|
3440
|
+
await removeEntry(target.candidate, { force: true });
|
|
3441
|
+
} catch (originalError) {
|
|
3442
|
+
if (index === 0) {
|
|
3443
|
+
if (moved.length === 1) {
|
|
3444
|
+
return await restoreUninstallCandidate(target.candidate, target.destination, operations, originalError);
|
|
3445
|
+
}
|
|
3446
|
+
return await rollbackMovedCandidates(moved, operations, originalError);
|
|
3447
|
+
}
|
|
3448
|
+
const results = [];
|
|
3449
|
+
for (const [restoreIndex, entry] of moved.entries()) {
|
|
3450
|
+
const result = restoreIndex < index ? await tryRestoreRemovedLink(entry.destination, entry.rawTarget, operations) : await tryRestoreCandidate(entry.candidate, entry.destination, operations);
|
|
3451
|
+
results.push({ destination: entry.destination, result });
|
|
3452
|
+
}
|
|
3453
|
+
throw uninstallRollbackError(results, originalError, "\uC9C0\uC6B4 \uACBD\uB85C");
|
|
3454
|
+
}
|
|
3063
3455
|
}
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3456
|
+
}
|
|
3457
|
+
async function uninstallSkill(context, operations = defaultOperations) {
|
|
3458
|
+
const targets = await planUninstallTargets(context);
|
|
3459
|
+
const moved = [];
|
|
3460
|
+
for (const target of targets) {
|
|
3461
|
+
const movedTarget = await moveUninstallCandidate(target, moved, operations);
|
|
3462
|
+
if (movedTarget) {
|
|
3463
|
+
moved.push(movedTarget);
|
|
3464
|
+
}
|
|
3068
3465
|
}
|
|
3069
|
-
|
|
3466
|
+
await removeUninstallCandidates(moved, operations);
|
|
3467
|
+
const agentResult = (agent) => ({
|
|
3468
|
+
action: moved.some((target) => target.agents.includes(agent)) ? "removed" : "absent",
|
|
3469
|
+
destination: destinationPath(context, agent)
|
|
3470
|
+
});
|
|
3471
|
+
const agents = { claude: agentResult("claude"), codex: agentResult("codex") };
|
|
3472
|
+
return {
|
|
3473
|
+
action: SKILL_AGENTS.some((agent) => agents[agent].action === "removed") ? "removed" : "absent",
|
|
3474
|
+
agents
|
|
3475
|
+
};
|
|
3070
3476
|
}
|
|
3071
3477
|
|
|
3072
3478
|
// src/formatters/table.ts
|
|
@@ -3142,9 +3548,16 @@ function outputSkillStatus(opts, status) {
|
|
|
3142
3548
|
rows: [
|
|
3143
3549
|
["\uC0C1\uD0DC", status.status],
|
|
3144
3550
|
["\uD604\uC7AC \uBC84\uC804", status.currentVersion],
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3551
|
+
...SKILL_AGENTS.flatMap((agent) => {
|
|
3552
|
+
const name = SKILL_AGENT_NAMES[agent];
|
|
3553
|
+
const agentStatus = status.agents[agent];
|
|
3554
|
+
return [
|
|
3555
|
+
[`${name} \uC0C1\uD0DC`, agentStatus.status],
|
|
3556
|
+
[`${name} \uC124\uCE58 \uBC84\uC804`, terminalText(agentStatus.installedVersion)],
|
|
3557
|
+
[`${name} \uC124\uCE58 \uACBD\uB85C`, terminalText(agentStatus.destination)],
|
|
3558
|
+
[`${name} \uB9C1\uD06C \uB300\uC0C1`, terminalText(agentStatus.linkTarget)]
|
|
3559
|
+
];
|
|
3560
|
+
}),
|
|
3148
3561
|
["\uBCF5\uAD6C \uBA85\uB839", skillRecoveryCommand(status.status) ?? "\uC870\uCE58 \uC5C6\uC74C"]
|
|
3149
3562
|
],
|
|
3150
3563
|
raw: status,
|
|
@@ -3159,7 +3572,10 @@ function outputSkillInstallResult(opts, result) {
|
|
|
3159
3572
|
["\uBCC0\uACBD \uC5EC\uBD80", result.changed ? "\uBCC0\uACBD\uB428" : "\uBCC0\uACBD \uC5C6\uC74C"],
|
|
3160
3573
|
["\uC774\uC804 \uC0C1\uD0DC", result.previousStatus.status],
|
|
3161
3574
|
["\uD604\uC7AC \uC0C1\uD0DC", result.status.status],
|
|
3162
|
-
|
|
3575
|
+
...SKILL_AGENTS.map((agent) => [
|
|
3576
|
+
`${SKILL_AGENT_NAMES[agent]} \uC124\uCE58 \uACBD\uB85C`,
|
|
3577
|
+
terminalText(result.status.agents[agent].destination)
|
|
3578
|
+
]),
|
|
3163
3579
|
["\uAD00\uB9AC \uC800\uC7A5\uC18C", terminalText(result.repositoryPath)],
|
|
3164
3580
|
[
|
|
3165
3581
|
"\uBC31\uC5C5 \uACBD\uB85C",
|
|
@@ -3175,7 +3591,14 @@ function outputSkillUninstallResult(opts, result) {
|
|
|
3175
3591
|
headers: ["\uD56D\uBAA9", "\uAC12"],
|
|
3176
3592
|
rows: [
|
|
3177
3593
|
["\uC791\uC5C5", result.action === "removed" ? "\uD65C\uC131 \uB9C1\uD06C \uC81C\uAC70 \uC644\uB8CC" : "\uD65C\uC131 \uB9C1\uD06C \uC5C6\uC74C"],
|
|
3178
|
-
|
|
3594
|
+
...SKILL_AGENTS.flatMap((agent) => {
|
|
3595
|
+
const name = SKILL_AGENT_NAMES[agent];
|
|
3596
|
+
const agentResult = result.agents[agent];
|
|
3597
|
+
return [
|
|
3598
|
+
[`${name} \uC124\uCE58 \uACBD\uB85C`, terminalText(agentResult.destination)],
|
|
3599
|
+
[`${name} \uACB0\uACFC`, agentResult.action === "removed" ? "\uD65C\uC131 \uB9C1\uD06C \uC81C\uAC70" : "\uD65C\uC131 \uB9C1\uD06C \uC5C6\uC74C"]
|
|
3600
|
+
];
|
|
3601
|
+
}),
|
|
3179
3602
|
["\uAD00\uB9AC \uC800\uC7A5\uC18C", "\uBCF4\uC874\uB428"]
|
|
3180
3603
|
],
|
|
3181
3604
|
raw: result,
|
|
@@ -3198,7 +3621,7 @@ async function showStatus(cmd, dependencies) {
|
|
|
3198
3621
|
}
|
|
3199
3622
|
function createInstallCommand(name, dependencies) {
|
|
3200
3623
|
return new import_commander3.Command(name).description(
|
|
3201
|
-
name === "install" ? "Claude Code \uC2A4\uD0AC\uC744 \uAD00\uB9AC \uC800\uC7A5\uC18C\uC5D0 \uC124\uCE58\uD55C\uB2E4" : "Claude Code \uC2A4\uD0AC\uC744 \uD604\uC7AC CLI \uBC84\uC804\uC73C\uB85C \uAC31\uC2E0\uD55C\uB2E4"
|
|
3624
|
+
name === "install" ? "Claude Code\xB7Codex \uC2A4\uD0AC\uC744 \uAD00\uB9AC \uC800\uC7A5\uC18C\uC5D0 \uC124\uCE58\uD55C\uB2E4" : "Claude Code\xB7Codex \uC2A4\uD0AC\uC744 \uD604\uC7AC CLI \uBC84\uC804\uC73C\uB85C \uAC31\uC2E0\uD55C\uB2E4"
|
|
3202
3625
|
).option("--force", "\uC0AC\uC6A9\uC790 \uD56D\uBAA9\uC774\uB098 \uC218\uC815\xB7\uC190\uC0C1\uB41C \uAD00\uB9AC \uC800\uC7A5\uC18C\uB97C \uBC31\uC5C5 \uD6C4 \uAD50\uCCB4\uD55C\uB2E4").action(async (_localOpts, cmd) => {
|
|
3203
3626
|
const opts = cmd.optsWithGlobals();
|
|
3204
3627
|
const context = dependencies.createContext();
|
|
@@ -3207,96 +3630,280 @@ function createInstallCommand(name, dependencies) {
|
|
|
3207
3630
|
});
|
|
3208
3631
|
}
|
|
3209
3632
|
function createSkillsCommand(dependencies = defaultDependencies) {
|
|
3210
|
-
const statusCommand = new import_commander3.Command("status").description("Claude Code \uC2A4\uD0AC\uC758 \uAD00\uB9AC \uC0C1\uD0DC\uB97C \uC870\uD68C\uD55C\uB2E4").action(async (_opts, cmd) => showStatus(cmd, dependencies));
|
|
3211
|
-
const uninstallCommand = new import_commander3.Command("uninstall").description("\uD65C\uC131 Claude Code \uC2A4\uD0AC \uB9C1\uD06C\uB97C \uC81C\uAC70\uD55C\uB2E4").action(async (_opts, cmd) => {
|
|
3633
|
+
const statusCommand = new import_commander3.Command("status").description("Claude Code\xB7Codex \uC2A4\uD0AC\uC758 \uAD00\uB9AC \uC0C1\uD0DC\uB97C \uC870\uD68C\uD55C\uB2E4").action(async (_opts, cmd) => showStatus(cmd, dependencies));
|
|
3634
|
+
const uninstallCommand = new import_commander3.Command("uninstall").description("\uD65C\uC131 Claude Code\xB7Codex \uC2A4\uD0AC \uB9C1\uD06C\uB97C \uC81C\uAC70\uD55C\uB2E4").action(async (_opts, cmd) => {
|
|
3212
3635
|
const opts = cmd.optsWithGlobals();
|
|
3213
3636
|
const context = dependencies.createContext();
|
|
3214
|
-
const
|
|
3215
|
-
const action = await dependencies.uninstall(context);
|
|
3637
|
+
const uninstalled = await dependencies.uninstall(context);
|
|
3216
3638
|
const result = {
|
|
3217
3639
|
schemaVersion: 1,
|
|
3218
|
-
action,
|
|
3219
|
-
changed: action === "removed",
|
|
3640
|
+
action: uninstalled.action,
|
|
3641
|
+
changed: uninstalled.action === "removed",
|
|
3220
3642
|
status: "missing",
|
|
3221
|
-
destination:
|
|
3222
|
-
repositoryPreserved: true
|
|
3643
|
+
destination: uninstalled.agents.claude.destination,
|
|
3644
|
+
repositoryPreserved: true,
|
|
3645
|
+
agents: uninstalled.agents
|
|
3223
3646
|
};
|
|
3224
3647
|
outputSkillUninstallResult(opts, result);
|
|
3225
3648
|
});
|
|
3226
|
-
return new import_commander3.Command("skills").description(`Claude Code \uC2A4\uD0AC(${SKILL_NAME3}) \uC124\uCE58 \uAD00\uB9AC`).addCommand(statusCommand).addCommand(createInstallCommand("install", dependencies)).addCommand(createInstallCommand("update", dependencies)).addCommand(uninstallCommand).action(async (_opts, cmd) => showStatus(cmd, dependencies));
|
|
3649
|
+
return new import_commander3.Command("skills").description(`Claude Code\xB7Codex \uC2A4\uD0AC(${SKILL_NAME3}) \uC124\uCE58 \uAD00\uB9AC`).addCommand(statusCommand).addCommand(createInstallCommand("install", dependencies)).addCommand(createInstallCommand("update", dependencies)).addCommand(uninstallCommand).action(async (_opts, cmd) => showStatus(cmd, dependencies));
|
|
3227
3650
|
}
|
|
3228
3651
|
var skillsCommand = createSkillsCommand();
|
|
3229
3652
|
|
|
3230
3653
|
// src/commands/doctor.ts
|
|
3231
3654
|
var import_commander4 = require("commander");
|
|
3232
3655
|
var import_chalk3 = __toESM(require("chalk"));
|
|
3233
|
-
var
|
|
3234
|
-
var
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3656
|
+
var SKILL_ERROR_REASON = "\uACF5\uAC1C \uC2A4\uD0AC \uC0C1\uD0DC\uB97C \uD310\uC815\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4";
|
|
3657
|
+
var defaultDependencies2 = {
|
|
3658
|
+
inspectCredentials: inspectCredentialsFile,
|
|
3659
|
+
inspectConfig: inspectConfigFile,
|
|
3660
|
+
resolveProfile: resolveProfileName,
|
|
3661
|
+
createSkillContext: createSkillManagerContext,
|
|
3662
|
+
inspectSkill: inspectAgentSkill,
|
|
3663
|
+
connection: {
|
|
3664
|
+
getUserAccessKey,
|
|
3665
|
+
getIaasCredential,
|
|
3666
|
+
getOptionalServiceCredential,
|
|
3667
|
+
verifyUserAccessKey,
|
|
3668
|
+
verifyIaas,
|
|
3669
|
+
verifyLogncrash,
|
|
3670
|
+
verifyNcr,
|
|
3671
|
+
verifyNcs
|
|
3672
|
+
}
|
|
3673
|
+
};
|
|
3674
|
+
async function resolveTargetProfile(cliProfile, dependencies) {
|
|
3241
3675
|
try {
|
|
3242
|
-
|
|
3243
|
-
} catch {
|
|
3244
|
-
|
|
3676
|
+
return await dependencies.resolveProfile(cliProfile);
|
|
3677
|
+
} catch (err) {
|
|
3678
|
+
if (err instanceof NhnCloudCliError) return null;
|
|
3679
|
+
throw err;
|
|
3245
3680
|
}
|
|
3681
|
+
}
|
|
3682
|
+
async function inspectAgentSkillForDoctor(dependencies, agent) {
|
|
3246
3683
|
try {
|
|
3247
|
-
const
|
|
3248
|
-
return {
|
|
3249
|
-
} catch {
|
|
3250
|
-
|
|
3684
|
+
const status = await dependencies.inspectSkill(dependencies.createSkillContext(), agent);
|
|
3685
|
+
return { ...status, recoveryCommand: skillRecoveryCommand(status.status) ?? null };
|
|
3686
|
+
} catch (err) {
|
|
3687
|
+
const code = typeof err === "object" && err !== null && "code" in err && typeof err.code === "string" ? err.code : void 0;
|
|
3688
|
+
return { status: "error", reason: code ? `${SKILL_ERROR_REASON}: ${code}` : SKILL_ERROR_REASON };
|
|
3251
3689
|
}
|
|
3252
3690
|
}
|
|
3253
|
-
|
|
3691
|
+
function connectionHasFailure(connection) {
|
|
3692
|
+
return connection.checked && Object.values(connection.targets).some((target) => target.status === "failed");
|
|
3693
|
+
}
|
|
3694
|
+
var CONNECTION_TARGETS = ["userAccessKey", "iaas", "logncrash", "ncr", "ncs"];
|
|
3695
|
+
function skipAll(reason) {
|
|
3696
|
+
return Object.fromEntries(
|
|
3697
|
+
CONNECTION_TARGETS.map((target) => [target, { status: "skipped", reason }])
|
|
3698
|
+
);
|
|
3699
|
+
}
|
|
3700
|
+
async function runVerify(verify) {
|
|
3254
3701
|
try {
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
return null;
|
|
3702
|
+
return await verify() ? { status: "ok" } : { status: "failed", reason: "auth" };
|
|
3703
|
+
} catch (err) {
|
|
3704
|
+
const exitCode = err instanceof NhnCloudCliError ? err.exitCode : EXIT_API_ERROR;
|
|
3705
|
+
return { status: "failed", reason: "error", exitCode };
|
|
3260
3706
|
}
|
|
3261
3707
|
}
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
console.log(` ${import_chalk3.default.red("\u274C \uBBF8\uC124\uC815")} \u2014 ${CREDENTIALS_PATH2} \uC5C6\uC74C. nhncloud configure \uB85C \uC124\uC815\uD558\uC138\uC694.`);
|
|
3269
|
-
} else if (creds.parseError) {
|
|
3270
|
-
console.log(` ${import_chalk3.default.red("\u274C \uD30C\uC2F1 \uC624\uB958")} \u2014 ${CREDENTIALS_PATH2} \uAC00 \uC62C\uBC14\uB978 JSON \uC778\uC9C0 \uD655\uC778\uD558\uC138\uC694.`);
|
|
3271
|
-
} else if (creds.profiles.length === 0) {
|
|
3272
|
-
console.log(` ${import_chalk3.default.yellow("\u26A0 profile \uC5C6\uC74C")} \u2014 nhncloud configure \uB85C \uC124\uC815\uD558\uC138\uC694.`);
|
|
3273
|
-
} else {
|
|
3274
|
-
console.log(` ${import_chalk3.default.green("\u2713 \uC124\uC815\uB428")} \u2014 profile: ${creds.profiles.join(", ")}`);
|
|
3275
|
-
console.log(` \uAE30\uBCF8 profile: ${defaultProfile ? import_chalk3.default.green(defaultProfile) : import_chalk3.default.gray("\uBBF8\uC9C0\uC815 (default \uC0AC\uC6A9)")}`);
|
|
3708
|
+
async function readRequired(read) {
|
|
3709
|
+
try {
|
|
3710
|
+
return { value: await read() };
|
|
3711
|
+
} catch (err) {
|
|
3712
|
+
const reason = err instanceof NhnCloudCliError ? "not-configured" : "profile-unavailable";
|
|
3713
|
+
return { skipped: { status: "skipped", reason } };
|
|
3276
3714
|
}
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
}
|
|
3284
|
-
|
|
3285
|
-
|
|
3715
|
+
}
|
|
3716
|
+
async function readAppkey(service, profileName, deps) {
|
|
3717
|
+
try {
|
|
3718
|
+
const credential = await deps.getOptionalServiceCredential(service, profileName);
|
|
3719
|
+
if (!credential?.appkey) return { skipped: { status: "skipped", reason: "not-configured" } };
|
|
3720
|
+
return { appkey: credential.appkey };
|
|
3721
|
+
} catch {
|
|
3722
|
+
return { skipped: { status: "skipped", reason: "profile-unavailable" } };
|
|
3723
|
+
}
|
|
3724
|
+
}
|
|
3725
|
+
async function checkConnection(profileName, credentials, profileSummary, deps) {
|
|
3726
|
+
if (credentials.state !== "ok" || profileName === null || profileSummary === void 0 || profileSummary.environment === "invalid") {
|
|
3727
|
+
return skipAll("profile-unavailable");
|
|
3728
|
+
}
|
|
3729
|
+
if (profileSummary.environment === "gov") return skipAll("gov-unsupported");
|
|
3730
|
+
const uakRead = await readRequired(() => deps.getUserAccessKey(profileName));
|
|
3731
|
+
const uak = "value" in uakRead ? uakRead.value : void 0;
|
|
3732
|
+
const userAccessKey = "value" in uakRead ? await runVerify(() => deps.verifyUserAccessKey(uakRead.value)) : uakRead.skipped;
|
|
3733
|
+
const iaasRead = await readRequired(() => deps.getIaasCredential(profileName));
|
|
3734
|
+
const iaasResult = "value" in iaasRead ? await runVerify(() => deps.verifyIaas(iaasRead.value)) : iaasRead.skipped;
|
|
3735
|
+
const checkAppkeyService = async (service, verify, usesOAuth) => {
|
|
3736
|
+
const read = await readAppkey(service, profileName, deps);
|
|
3737
|
+
if ("skipped" in read) return read.skipped;
|
|
3738
|
+
if (uak === void 0) return { status: "skipped", reason: "uak-missing" };
|
|
3739
|
+
if (usesOAuth && userAccessKey.status !== "ok") return { status: "skipped", reason: "uak-failed" };
|
|
3740
|
+
return runVerify(() => verify(uak, read.appkey));
|
|
3741
|
+
};
|
|
3742
|
+
const logncrash = await checkAppkeyService("logncrash", deps.verifyLogncrash, true);
|
|
3743
|
+
const ncr = await checkAppkeyService("ncr", deps.verifyNcr, false);
|
|
3744
|
+
const ncs = await checkAppkeyService("ncs", deps.verifyNcs, true);
|
|
3745
|
+
return { userAccessKey, iaas: iaasResult, logncrash, ncr, ncs };
|
|
3746
|
+
}
|
|
3747
|
+
async function buildDoctorReport(options, dependencies) {
|
|
3748
|
+
const credentials = await dependencies.inspectCredentials();
|
|
3749
|
+
const config = await dependencies.inspectConfig();
|
|
3750
|
+
const profileName = await resolveTargetProfile(options.profile, dependencies);
|
|
3751
|
+
const profileSummary = credentials.state === "ok" && profileName !== null ? credentials.profiles.find((summary) => summary.name === profileName) : void 0;
|
|
3752
|
+
const connection = options.checkConnection ? {
|
|
3753
|
+
checked: true,
|
|
3754
|
+
profile: profileName,
|
|
3755
|
+
targets: await checkConnection(profileName, credentials, profileSummary, dependencies.connection)
|
|
3756
|
+
} : { checked: false };
|
|
3757
|
+
const claude = await inspectAgentSkillForDoctor(dependencies, "claude");
|
|
3758
|
+
const codex = await inspectAgentSkillForDoctor(dependencies, "codex");
|
|
3759
|
+
const ready = profileSummary !== void 0 && profileSummary.environment !== "invalid" && profileSummary.blocks.length > 0 && !connectionHasFailure(connection);
|
|
3760
|
+
return {
|
|
3761
|
+
schemaVersion: 1,
|
|
3762
|
+
ready,
|
|
3763
|
+
credentials,
|
|
3764
|
+
config,
|
|
3765
|
+
profile: { name: profileName, exists: profileSummary !== void 0 },
|
|
3766
|
+
connection,
|
|
3767
|
+
skills: { agents: { claude, codex } }
|
|
3768
|
+
};
|
|
3769
|
+
}
|
|
3770
|
+
function line(text = "") {
|
|
3771
|
+
process.stdout.write(`${text}
|
|
3772
|
+
`);
|
|
3773
|
+
}
|
|
3774
|
+
function printCredentialsSection(credentials) {
|
|
3775
|
+
const filePath = sanitizeForTerminal(credentials.path);
|
|
3776
|
+
const reason = sanitizeForTerminal(credentials.reason ?? "");
|
|
3777
|
+
line(import_chalk3.default.bold("\uC790\uACA9\uC99D\uBA85"));
|
|
3778
|
+
switch (credentials.state) {
|
|
3779
|
+
case "missing":
|
|
3780
|
+
line(` ${import_chalk3.default.red("\u274C \uBBF8\uC124\uC815")} \u2014 ${filePath} \uC5C6\uC74C. nhncloud configure \uB85C \uC124\uC815\uD558\uC138\uC694.`);
|
|
3781
|
+
break;
|
|
3782
|
+
case "invalid":
|
|
3783
|
+
line(` ${import_chalk3.default.red("\u274C \uD615\uC2DD \uC624\uB958")} \u2014 ${filePath}: ${reason}`);
|
|
3784
|
+
break;
|
|
3785
|
+
case "unreadable":
|
|
3786
|
+
line(` ${import_chalk3.default.red("\u274C \uC77D\uAE30 \uC2E4\uD328")} \u2014 ${filePath}: ${reason}`);
|
|
3787
|
+
break;
|
|
3788
|
+
case "ok":
|
|
3789
|
+
if (credentials.profiles.length === 0) {
|
|
3790
|
+
line(` ${import_chalk3.default.yellow("\u26A0 profile \uC5C6\uC74C")} \u2014 nhncloud configure \uB85C \uC124\uC815\uD558\uC138\uC694.`);
|
|
3791
|
+
break;
|
|
3792
|
+
}
|
|
3793
|
+
line(` ${import_chalk3.default.green("\u2713 \uC124\uC815\uB428")} \u2014 profile:`);
|
|
3794
|
+
for (const summary of credentials.profiles) {
|
|
3795
|
+
const name = sanitizeForTerminal(summary.name);
|
|
3796
|
+
const blocks = summary.blocks.map(sanitizeForTerminal).join(", ") || "-";
|
|
3797
|
+
if (summary.environment === "invalid") {
|
|
3798
|
+
line(` ${name} ${import_chalk3.default.yellow("\u26A0 environment \uAC12\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4")} [${blocks}]`);
|
|
3799
|
+
} else {
|
|
3800
|
+
line(` ${name}${summary.environment === "gov" ? " (gov)" : ""} [${blocks}]`);
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3803
|
+
break;
|
|
3804
|
+
}
|
|
3805
|
+
if (credentials.permissions === "too-open") {
|
|
3806
|
+
line(` ${import_chalk3.default.yellow("\u26A0 \uD30C\uC77C \uAD8C\uD55C\uC774 \uB113\uC2B5\uB2C8\uB2E4")} \u2014 chmod 600 ${filePath}`);
|
|
3807
|
+
}
|
|
3808
|
+
}
|
|
3809
|
+
function printConfigSection(config) {
|
|
3810
|
+
line(import_chalk3.default.bold("\n\uC124\uC815 \uD30C\uC77C"));
|
|
3811
|
+
if (config.state === "invalid" || config.state === "unreadable") {
|
|
3812
|
+
line(
|
|
3813
|
+
` ${import_chalk3.default.red(config.state === "invalid" ? "\u274C \uD615\uC2DD \uC624\uB958" : "\u274C \uC77D\uAE30 \uC2E4\uD328")} \u2014 ${sanitizeForTerminal(config.path)}: ${sanitizeForTerminal(config.reason ?? "")}`
|
|
3286
3814
|
);
|
|
3815
|
+
}
|
|
3816
|
+
line(
|
|
3817
|
+
` \uAE30\uBCF8 profile: ${config.defaultProfile ? import_chalk3.default.green(sanitizeForTerminal(config.defaultProfile)) : import_chalk3.default.gray("\uBBF8\uC9C0\uC815 (default \uC0AC\uC6A9)")}`
|
|
3818
|
+
);
|
|
3819
|
+
}
|
|
3820
|
+
function printProfileSection(profile) {
|
|
3821
|
+
line(import_chalk3.default.bold("\n\uB300\uC0C1 profile"));
|
|
3822
|
+
if (profile.name === null) {
|
|
3823
|
+
line(` ${import_chalk3.default.red("\u274C \uD574\uC11D \uC2E4\uD328")} \u2014 config.json \uC744 \uBA3C\uC800 \uACE0\uCE58\uC138\uC694.`);
|
|
3824
|
+
} else if (profile.exists) {
|
|
3825
|
+
line(` ${import_chalk3.default.green(`\u2713 ${sanitizeForTerminal(profile.name)}`)}`);
|
|
3287
3826
|
} else {
|
|
3288
|
-
|
|
3289
|
-
` ${
|
|
3827
|
+
line(
|
|
3828
|
+
` ${import_chalk3.default.yellow(`\u26A0 ${sanitizeForTerminal(profile.name)} \uC5C6\uC74C`)} \u2014 nhncloud configure \uB85C \uC124\uC815\uD558\uC138\uC694.`
|
|
3290
3829
|
);
|
|
3291
3830
|
}
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3831
|
+
}
|
|
3832
|
+
function printSkillLine(agent, skill) {
|
|
3833
|
+
const name = SKILL_AGENT_NAMES[agent];
|
|
3834
|
+
if (skill.status === "error") {
|
|
3835
|
+
line(` ${name}: ${import_chalk3.default.yellow("\u26A0 error")} \u2014 ${sanitizeForTerminal(skill.reason)}`);
|
|
3836
|
+
} else if (skill.status === "current") {
|
|
3837
|
+
const version = sanitizeForTerminal(skill.installedVersion ?? skill.currentVersion);
|
|
3838
|
+
line(` ${name}: ${import_chalk3.default.green(`\u2713 current (${version})`)}`);
|
|
3839
|
+
} else if (skill.status === "missing") {
|
|
3840
|
+
line(` ${name}: ${import_chalk3.default.gray(`\uBBF8\uC124\uCE58 \u2014 ${skill.recoveryCommand}`)}`);
|
|
3295
3841
|
} else {
|
|
3296
|
-
|
|
3842
|
+
line(` ${name}: ${import_chalk3.default.yellow(`\u26A0 ${skill.status}`)} \u2014 ${skill.recoveryCommand}`);
|
|
3297
3843
|
}
|
|
3298
|
-
|
|
3299
|
-
|
|
3844
|
+
}
|
|
3845
|
+
function printSkillSection(agents) {
|
|
3846
|
+
line(import_chalk3.default.bold("\n\uACF5\uAC1C \uC2A4\uD0AC"));
|
|
3847
|
+
for (const agent of SKILL_AGENTS) printSkillLine(agent, agents[agent]);
|
|
3848
|
+
}
|
|
3849
|
+
var SKIP_REASONS = {
|
|
3850
|
+
"not-configured": "\uC124\uC815 \uC5C6\uC74C",
|
|
3851
|
+
"uak-missing": "\uACF5\uD1B5 userAccessKey \uC5C6\uC74C",
|
|
3852
|
+
"uak-failed": "userAccessKey \uD655\uC778\uC774 \uC131\uACF5\uD558\uC9C0 \uC54A\uC544 \uAC74\uB108\uB700",
|
|
3853
|
+
"gov-unsupported": "\uACF5\uACF5\uB9DD profile \uC740 \uC5F0\uACB0 \uD655\uC778\uC744 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC74C",
|
|
3854
|
+
"profile-unavailable": "\uB300\uC0C1 profile \uC744 \uC77D\uC744 \uC218 \uC5C6\uC74C"
|
|
3855
|
+
};
|
|
3856
|
+
function printConnectionSection(connection) {
|
|
3857
|
+
if (!connection.checked) return;
|
|
3858
|
+
line(import_chalk3.default.bold("\n\uC5F0\uACB0 \uD655\uC778"));
|
|
3859
|
+
for (const target of CONNECTION_TARGETS) {
|
|
3860
|
+
const result = connection.targets[target];
|
|
3861
|
+
const label = ` ${target}:`;
|
|
3862
|
+
if (result.status === "ok") {
|
|
3863
|
+
const region = target === "ncr" || target === "ncs" ? " (kr1)" : "";
|
|
3864
|
+
line(`${label} ${import_chalk3.default.green(`\u2713 \uC131\uACF5${region}`)}`);
|
|
3865
|
+
} else if (result.status === "failed" && result.reason === "auth") {
|
|
3866
|
+
line(`${label} ${import_chalk3.default.red("\u274C \uC778\uC99D \uC2E4\uD328")} \u2014 \uD0A4\uB098 appkey \uB97C \uD655\uC778\uD558\uC138\uC694.`);
|
|
3867
|
+
} else if (result.status === "failed") {
|
|
3868
|
+
line(`${label} ${import_chalk3.default.red(`\u274C \uC624\uB958 (\uC885\uB8CC \uCF54\uB4DC ${result.exitCode ?? EXIT_API_ERROR})`)}`);
|
|
3869
|
+
} else {
|
|
3870
|
+
const reason = result.reason ? SKIP_REASONS[result.reason] ?? result.reason : "";
|
|
3871
|
+
line(`${label} ${import_chalk3.default.gray(`\uAC74\uB108\uB700 \u2014 ${reason}`)}`);
|
|
3872
|
+
}
|
|
3873
|
+
}
|
|
3874
|
+
}
|
|
3875
|
+
function printText(report) {
|
|
3876
|
+
line(import_chalk3.default.bold("\n\u{1F50D} nhncloud-cli \uC9C4\uB2E8\n"));
|
|
3877
|
+
printCredentialsSection(report.credentials);
|
|
3878
|
+
printConfigSection(report.config);
|
|
3879
|
+
printProfileSection(report.profile);
|
|
3880
|
+
printConnectionSection(report.connection);
|
|
3881
|
+
printSkillSection(report.skills.agents);
|
|
3882
|
+
line();
|
|
3883
|
+
if (report.ready) {
|
|
3884
|
+
line(import_chalk3.default.green("\u2713 \uAE30\uBCF8 \uC124\uC815\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
|
|
3885
|
+
} else {
|
|
3886
|
+
line(import_chalk3.default.yellow("\u26A0 \uC124\uC815\uC774 \uD544\uC694\uD569\uB2C8\uB2E4: nhncloud configure"));
|
|
3887
|
+
}
|
|
3888
|
+
line();
|
|
3889
|
+
}
|
|
3890
|
+
function createDoctorCommand(dependencies = defaultDependencies2) {
|
|
3891
|
+
return new import_commander4.Command("doctor").description("\uC790\uACA9\uC99D\uBA85\xB7\uC124\uC815\xB7\uC2A4\uD0AC \uC0C1\uD0DC\uB97C \uC9C4\uB2E8\uD55C\uB2E4(\uAE30\uBCF8 \uC624\uD504\uB77C\uC778, --check-connection \uC73C\uB85C \uC5F0\uACB0 \uD655\uC778)").option("--profile <name>", "\uC9C4\uB2E8\uD560 profile \uC774\uB984").option("--check-connection", "\uB300\uC0C1 profile \uC758 \uC790\uACA9\uC99D\uBA85\uC73C\uB85C \uC2E4\uC81C \uC5F0\uACB0\uC744 \uD655\uC778\uD55C\uB2E4 (\uC678\uBD80 API \uD638\uCD9C)").action(async (_opts, cmd) => {
|
|
3892
|
+
const opts = cmd.optsWithGlobals();
|
|
3893
|
+
const report = await buildDoctorReport(
|
|
3894
|
+
{ profile: opts.profile, checkConnection: opts.checkConnection },
|
|
3895
|
+
dependencies
|
|
3896
|
+
);
|
|
3897
|
+
if (opts.json) {
|
|
3898
|
+
printJson(report);
|
|
3899
|
+
} else if (opts.quiet) {
|
|
3900
|
+
process.stdout.write(report.ready ? "ready\n" : "not-ready\n");
|
|
3901
|
+
} else {
|
|
3902
|
+
printText(report);
|
|
3903
|
+
}
|
|
3904
|
+
});
|
|
3905
|
+
}
|
|
3906
|
+
var doctorCommand = createDoctorCommand();
|
|
3300
3907
|
|
|
3301
3908
|
// src/commands/logncrash/search.ts
|
|
3302
3909
|
var import_commander5 = require("commander");
|
|
@@ -3545,19 +4152,19 @@ var VALID_LEVELS = ["DEBUG", "INFO", "WARN", "ERROR", "FATAL"];
|
|
|
3545
4152
|
function resolveBody(opts) {
|
|
3546
4153
|
if (opts.body !== void 0) return opts.body;
|
|
3547
4154
|
if (opts.file !== void 0) {
|
|
3548
|
-
let
|
|
4155
|
+
let stat4;
|
|
3549
4156
|
try {
|
|
3550
|
-
|
|
4157
|
+
stat4 = (0, import_node_fs3.statSync)(opts.file);
|
|
3551
4158
|
} catch (e) {
|
|
3552
4159
|
const reason = e.code ?? (e instanceof Error ? e.message : String(e));
|
|
3553
4160
|
throw new NhnCloudCliError(`\uB85C\uADF8 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${opts.file} (${reason})`, EXIT_PARAM_ERROR);
|
|
3554
4161
|
}
|
|
3555
|
-
if (!
|
|
4162
|
+
if (!stat4.isFile()) {
|
|
3556
4163
|
throw new NhnCloudCliError(`\uB85C\uADF8 \uD30C\uC77C\uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${opts.file}`, EXIT_PARAM_ERROR);
|
|
3557
4164
|
}
|
|
3558
|
-
if (
|
|
4165
|
+
if (stat4.size > MAX_LOG_BYTES) {
|
|
3559
4166
|
throw new NhnCloudCliError(
|
|
3560
|
-
`\uB85C\uADF8 \uD30C\uC77C\uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4: ${
|
|
4167
|
+
`\uB85C\uADF8 \uD30C\uC77C\uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4: ${stat4.size} \uBC14\uC774\uD2B8 (\uD55C\uB3C4 ${MAX_LOG_BYTES} \uBC14\uC774\uD2B8).`,
|
|
3561
4168
|
EXIT_PARAM_ERROR
|
|
3562
4169
|
);
|
|
3563
4170
|
}
|
|
@@ -3628,22 +4235,22 @@ credentials.json \uC5D0 "appkey": "<appkey>" \uB97C \uCD94\uAC00\uD558\uC138\uC6
|
|
|
3628
4235
|
|
|
3629
4236
|
// src/commands/logncrash/export.ts
|
|
3630
4237
|
var import_commander7 = require("commander");
|
|
3631
|
-
var
|
|
4238
|
+
var import_promises4 = require("fs/promises");
|
|
3632
4239
|
var import_node_fs4 = require("fs");
|
|
3633
4240
|
var import_node_crypto4 = require("crypto");
|
|
3634
4241
|
var MAX_TOTAL = 1e5;
|
|
3635
|
-
var defaultExportFileOps = { appendFile:
|
|
3636
|
-
function assertWritable(
|
|
4242
|
+
var defaultExportFileOps = { appendFile: import_promises4.appendFile, rename: import_promises4.rename };
|
|
4243
|
+
function assertWritable(path4, force) {
|
|
3637
4244
|
if (force) return;
|
|
3638
4245
|
try {
|
|
3639
|
-
(0, import_node_fs4.statSync)(
|
|
4246
|
+
(0, import_node_fs4.statSync)(path4);
|
|
3640
4247
|
} catch (e) {
|
|
3641
4248
|
if (e.code === "ENOENT") return;
|
|
3642
4249
|
const reason = e.code ?? (e instanceof Error ? e.message : String(e));
|
|
3643
|
-
throw new NhnCloudCliError(`--output \uACBD\uB85C\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${
|
|
4250
|
+
throw new NhnCloudCliError(`--output \uACBD\uB85C\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${path4} (${reason})`, EXIT_PARAM_ERROR);
|
|
3644
4251
|
}
|
|
3645
4252
|
throw new NhnCloudCliError(
|
|
3646
|
-
`--output \uB300\uC0C1\uC774 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4: ${
|
|
4253
|
+
`--output \uB300\uC0C1\uC774 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4: ${path4}. \uB36E\uC5B4\uC4F0\uB824\uBA74 --force \uB97C \uC4F0\uC138\uC694.`,
|
|
3647
4254
|
EXIT_PARAM_ERROR
|
|
3648
4255
|
);
|
|
3649
4256
|
}
|
|
@@ -3754,7 +4361,7 @@ function createExportCommand(finalizeOps) {
|
|
|
3754
4361
|
} catch (err) {
|
|
3755
4362
|
if (failureOrigin !== "search" || !(err instanceof LogncrashServerError)) throw err;
|
|
3756
4363
|
await endAndClose(stream);
|
|
3757
|
-
await (0,
|
|
4364
|
+
await (0, import_promises4.truncate)(tmp, checkpoint.bytesWritten);
|
|
3758
4365
|
stream = (0, import_node_fs4.createWriteStream)(tmp, { encoding: "utf-8", flags: "a" });
|
|
3759
4366
|
bytePosition = checkpoint.bytesWritten;
|
|
3760
4367
|
count = checkpoint.count;
|
|
@@ -3781,14 +4388,14 @@ function createExportCommand(finalizeOps) {
|
|
|
3781
4388
|
stream.end();
|
|
3782
4389
|
});
|
|
3783
4390
|
if (count === 0) {
|
|
3784
|
-
await (0,
|
|
4391
|
+
await (0, import_promises4.rm)(tmp, { force: true }).catch(() => {
|
|
3785
4392
|
});
|
|
3786
4393
|
throw failure;
|
|
3787
4394
|
}
|
|
3788
4395
|
const partial = `${opts.output}.partial`;
|
|
3789
4396
|
try {
|
|
3790
|
-
if (format === "json") await (0,
|
|
3791
|
-
await (0,
|
|
4397
|
+
if (format === "json") await (0, import_promises4.appendFile)(tmp, "]\n");
|
|
4398
|
+
await (0, import_promises4.rename)(tmp, partial);
|
|
3792
4399
|
} catch {
|
|
3793
4400
|
process.stderr.write(
|
|
3794
4401
|
`\uACBD\uACE0: \uBD80\uBD84 \uACB0\uACFC\uB97C ${partial} \uC5D0 \uB0A8\uAE30\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uC784\uC2DC \uD30C\uC77C: ${tmp}
|
|
@@ -3830,7 +4437,7 @@ function createExportCommand(finalizeOps) {
|
|
|
3830
4437
|
throw new NhnCloudCliError(message, EXIT_PARAM_ERROR);
|
|
3831
4438
|
}
|
|
3832
4439
|
stopSpinner(true, `${count}\uAC74 \uCD94\uCD9C \uC644\uB8CC`);
|
|
3833
|
-
await (0,
|
|
4440
|
+
await (0, import_promises4.rm)(`${opts.output}.partial`, { force: true }).catch(() => {
|
|
3834
4441
|
});
|
|
3835
4442
|
if (count >= MAX_TOTAL && (total > MAX_TOTAL || hasUnqueriedWindows)) {
|
|
3836
4443
|
const totalDescription = hasUnqueriedWindows ? `\uC870\uD68C\uD55C \uCC3D\uC5D0\uC11C ${total}\uAC74\uC744 \uD655\uC778\uD588\uACE0 \uB0A8\uC740 \uCC3D\uC744 \uC870\uD68C\uD558\uC9C0 \uC54A\uC740 \uCC44` : `\uC804\uCCB4 ${total}\uAC74 \uC911`;
|
|
@@ -4448,7 +5055,7 @@ var binariesCommand = new import_commander15.Command("binaries").description("\u
|
|
|
4448
5055
|
// src/commands/deploy/upload.ts
|
|
4449
5056
|
var import_commander16 = require("commander");
|
|
4450
5057
|
var import_node_fs5 = require("fs");
|
|
4451
|
-
var
|
|
5058
|
+
var import_node_path6 = require("path");
|
|
4452
5059
|
var MAX_UPLOAD_BYTES = 512 * 1024 * 1024;
|
|
4453
5060
|
function parsePositiveInt2(value, flag) {
|
|
4454
5061
|
if (value === void 0) return void 0;
|
|
@@ -4468,9 +5075,9 @@ var uploadCommand = new import_commander16.Command("upload").description("\uB85C
|
|
|
4468
5075
|
}
|
|
4469
5076
|
const artifactId = requireCoordinate(opts.artifactId, "--artifact-id");
|
|
4470
5077
|
const filePath = opts.file;
|
|
4471
|
-
let
|
|
5078
|
+
let stat4;
|
|
4472
5079
|
try {
|
|
4473
|
-
|
|
5080
|
+
stat4 = (0, import_node_fs5.statSync)(filePath);
|
|
4474
5081
|
} catch (e) {
|
|
4475
5082
|
const reason = e.code ?? (e instanceof Error ? e.message : String(e));
|
|
4476
5083
|
throw new NhnCloudCliError(
|
|
@@ -4478,17 +5085,17 @@ var uploadCommand = new import_commander16.Command("upload").description("\uB85C
|
|
|
4478
5085
|
EXIT_PARAM_ERROR
|
|
4479
5086
|
);
|
|
4480
5087
|
}
|
|
4481
|
-
if (!
|
|
5088
|
+
if (!stat4.isFile()) {
|
|
4482
5089
|
throw new NhnCloudCliError(`--file \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${filePath}`, EXIT_PARAM_ERROR);
|
|
4483
5090
|
}
|
|
4484
|
-
if (
|
|
5091
|
+
if (stat4.size > MAX_UPLOAD_BYTES) {
|
|
4485
5092
|
throw new NhnCloudCliError(
|
|
4486
|
-
`--file \uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${
|
|
5093
|
+
`--file \uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${stat4.size} \uBC14\uC774\uD2B8). \uC5C5\uB85C\uB4DC \uD55C\uB3C4 ${MAX_UPLOAD_BYTES} \uBC14\uC774\uD2B8.`,
|
|
4487
5094
|
EXIT_PARAM_ERROR
|
|
4488
5095
|
);
|
|
4489
5096
|
}
|
|
4490
5097
|
const fileBuffer = (0, import_node_fs5.readFileSync)(filePath);
|
|
4491
|
-
const fileName = (0,
|
|
5098
|
+
const fileName = (0, import_node_path6.basename)(filePath);
|
|
4492
5099
|
const { client, profileName } = await createDeployClient(opts.profile);
|
|
4493
5100
|
const appKey = await resolveDeployAppKey(profileName);
|
|
4494
5101
|
startSpinner("\uBC14\uC774\uB108\uB9AC \uC5C5\uB85C\uB4DC \uC911...");
|
|
@@ -4534,20 +5141,20 @@ function parsePositiveInt3(value, flag) {
|
|
|
4534
5141
|
}
|
|
4535
5142
|
return Number(value);
|
|
4536
5143
|
}
|
|
4537
|
-
function assertWritable2(
|
|
5144
|
+
function assertWritable2(path4, force) {
|
|
4538
5145
|
if (force) return;
|
|
4539
5146
|
try {
|
|
4540
|
-
(0, import_node_fs6.statSync)(
|
|
5147
|
+
(0, import_node_fs6.statSync)(path4);
|
|
4541
5148
|
} catch (e) {
|
|
4542
5149
|
if (e.code === "ENOENT") return;
|
|
4543
5150
|
const reason = e.code ?? (e instanceof Error ? e.message : String(e));
|
|
4544
5151
|
throw new NhnCloudCliError(
|
|
4545
|
-
`-o \uACBD\uB85C\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${
|
|
5152
|
+
`-o \uACBD\uB85C\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${path4} (${reason})`,
|
|
4546
5153
|
EXIT_PARAM_ERROR
|
|
4547
5154
|
);
|
|
4548
5155
|
}
|
|
4549
5156
|
throw new NhnCloudCliError(
|
|
4550
|
-
`-o \uB300\uC0C1\uC774 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4: ${
|
|
5157
|
+
`-o \uB300\uC0C1\uC774 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4: ${path4}. \uB36E\uC5B4\uC4F0\uB824\uBA74 --force \uB97C \uC4F0\uC138\uC694.`,
|
|
4551
5158
|
EXIT_PARAM_ERROR
|
|
4552
5159
|
);
|
|
4553
5160
|
}
|
|
@@ -4890,8 +5497,8 @@ var InstanceClient = class {
|
|
|
4890
5497
|
return this.serverAction(id, { revertResize: null });
|
|
4891
5498
|
}
|
|
4892
5499
|
async listFlavors(params = {}) {
|
|
4893
|
-
const
|
|
4894
|
-
const url = `${this.computeEndpoint}${
|
|
5500
|
+
const path4 = params.detail ? "/flavors/detail" : "/flavors";
|
|
5501
|
+
const url = `${this.computeEndpoint}${path4}`;
|
|
4895
5502
|
const searchParams = {};
|
|
4896
5503
|
if (params.minDisk !== void 0) searchParams["minDisk"] = params.minDisk;
|
|
4897
5504
|
if (params.minRam !== void 0) searchParams["minRam"] = params.minRam;
|
|
@@ -6571,9 +7178,9 @@ var createCommand5 = new import_commander33.Command("create").description("\uC77
|
|
|
6571
7178
|
}
|
|
6572
7179
|
let userDataBase64;
|
|
6573
7180
|
if (opts.userData !== void 0) {
|
|
6574
|
-
let
|
|
7181
|
+
let stat4;
|
|
6575
7182
|
try {
|
|
6576
|
-
|
|
7183
|
+
stat4 = (0, import_node_fs7.statSync)(opts.userData);
|
|
6577
7184
|
} catch (e) {
|
|
6578
7185
|
const reason = e.code ?? (e instanceof Error ? e.message : String(e));
|
|
6579
7186
|
throw new NhnCloudCliError(
|
|
@@ -6581,15 +7188,15 @@ var createCommand5 = new import_commander33.Command("create").description("\uC77
|
|
|
6581
7188
|
EXIT_PARAM_ERROR
|
|
6582
7189
|
);
|
|
6583
7190
|
}
|
|
6584
|
-
if (!
|
|
7191
|
+
if (!stat4.isFile()) {
|
|
6585
7192
|
throw new NhnCloudCliError(
|
|
6586
7193
|
`--user-data \uAC00 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${opts.userData}`,
|
|
6587
7194
|
EXIT_PARAM_ERROR
|
|
6588
7195
|
);
|
|
6589
7196
|
}
|
|
6590
|
-
if (
|
|
7197
|
+
if (stat4.size > 49149) {
|
|
6591
7198
|
throw new NhnCloudCliError(
|
|
6592
|
-
`--user-data \uAC00 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${
|
|
7199
|
+
`--user-data \uAC00 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${stat4.size} \uBC14\uC774\uD2B8). base64 \uC778\uCF54\uB529 \uD6C4 65535 \uBC14\uC774\uD2B8 \uD55C\uB3C4\uB77C raw 49149 \uBC14\uC774\uD2B8\uAE4C\uC9C0\uB9CC \uD5C8\uC6A9\uB429\uB2C8\uB2E4.`,
|
|
6593
7200
|
EXIT_PARAM_ERROR
|
|
6594
7201
|
);
|
|
6595
7202
|
}
|
|
@@ -6874,9 +7481,9 @@ var import_node_fs8 = require("fs");
|
|
|
6874
7481
|
var import_node_crypto5 = require("crypto");
|
|
6875
7482
|
var import_chalk12 = __toESM(require("chalk"));
|
|
6876
7483
|
function resolvePublicKey(value) {
|
|
6877
|
-
let
|
|
7484
|
+
let stat4;
|
|
6878
7485
|
try {
|
|
6879
|
-
|
|
7486
|
+
stat4 = (0, import_node_fs8.statSync)(value);
|
|
6880
7487
|
} catch (e) {
|
|
6881
7488
|
const err = e;
|
|
6882
7489
|
if (err.code && err.code !== "ENOENT") {
|
|
@@ -6887,7 +7494,7 @@ function resolvePublicKey(value) {
|
|
|
6887
7494
|
}
|
|
6888
7495
|
return value;
|
|
6889
7496
|
}
|
|
6890
|
-
if (!
|
|
7497
|
+
if (!stat4.isFile()) {
|
|
6891
7498
|
throw new NhnCloudCliError(`--public-key \uAC00 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${value}`, EXIT_PARAM_ERROR);
|
|
6892
7499
|
}
|
|
6893
7500
|
return (0, import_node_fs8.readFileSync)(value, "utf-8").trim();
|
|
@@ -7194,12 +7801,12 @@ var HarborClient = class {
|
|
|
7194
7801
|
* ky.get() 이 Response 를 반환하므로 .json() 과 .headers.get("link") 를 함께 사용한다
|
|
7195
7802
|
* (체이닝하면 헤더를 못 본다 — 기존 NCR client 의 .json<T>() 체이닝 패턴과 다름).
|
|
7196
7803
|
*/
|
|
7197
|
-
async getAllPages(
|
|
7804
|
+
async getAllPages(path4) {
|
|
7198
7805
|
const acc = [];
|
|
7199
7806
|
let page = 1;
|
|
7200
7807
|
try {
|
|
7201
7808
|
for (; ; ) {
|
|
7202
|
-
const url = `https://${this.host}${
|
|
7809
|
+
const url = `https://${this.host}${path4}?page=${page}&page_size=${PAGE_SIZE}`;
|
|
7203
7810
|
const res = await import_ky13.default.get(url, {
|
|
7204
7811
|
headers: this.basicAuthHeaders(),
|
|
7205
7812
|
retry: 0,
|
|
@@ -7439,15 +8046,15 @@ function commandPath(command) {
|
|
|
7439
8046
|
return names.join(" ");
|
|
7440
8047
|
}
|
|
7441
8048
|
function collectCommand(command) {
|
|
7442
|
-
const
|
|
7443
|
-
if (!
|
|
8049
|
+
const path4 = commandPath(command);
|
|
8050
|
+
if (!path4 || path4 === "help") return null;
|
|
7444
8051
|
return {
|
|
7445
|
-
path:
|
|
8052
|
+
path: path4,
|
|
7446
8053
|
description: command.description() || command.summary() || "",
|
|
7447
8054
|
arguments: command.registeredArguments.map((arg) => arg.name()),
|
|
7448
8055
|
options: command.options.filter((option) => !option.hidden).map((option) => option.flags),
|
|
7449
8056
|
subcommands: command.commands.map((subcommand) => subcommand.name()).filter((name) => name !== "help"),
|
|
7450
|
-
...
|
|
8057
|
+
...path4 === "commands" ? { metadata: true } : {}
|
|
7451
8058
|
};
|
|
7452
8059
|
}
|
|
7453
8060
|
function collectCommandCatalog(program2) {
|
|
@@ -7486,7 +8093,7 @@ function createCommandsCommand(program2) {
|
|
|
7486
8093
|
var import_commander48 = require("commander");
|
|
7487
8094
|
|
|
7488
8095
|
// src/commands/nks/helpers.ts
|
|
7489
|
-
var
|
|
8096
|
+
var import_promises5 = require("fs/promises");
|
|
7490
8097
|
|
|
7491
8098
|
// src/services/nks/client.ts
|
|
7492
8099
|
var import_ky14 = __toESM(require("ky"));
|
|
@@ -7936,15 +8543,15 @@ var NksClient = class {
|
|
|
7936
8543
|
throw toNhnCloudCliError(err);
|
|
7937
8544
|
}
|
|
7938
8545
|
}
|
|
7939
|
-
async getFlatNamedResource(
|
|
7940
|
-
const raw = await this.getJson(
|
|
8546
|
+
async getFlatNamedResource(path4, errorMessage) {
|
|
8547
|
+
const raw = await this.getJson(path4);
|
|
7941
8548
|
if (!isNksNamedResource(raw)) {
|
|
7942
8549
|
throw new NhnCloudCliError(errorMessage, EXIT_API_ERROR);
|
|
7943
8550
|
}
|
|
7944
8551
|
return raw;
|
|
7945
8552
|
}
|
|
7946
|
-
async getJson(
|
|
7947
|
-
const url = `${this.nksEndpoint}${
|
|
8553
|
+
async getJson(path4, searchParams) {
|
|
8554
|
+
const url = `${this.nksEndpoint}${path4}`;
|
|
7948
8555
|
try {
|
|
7949
8556
|
return await import_ky14.default.get(url, {
|
|
7950
8557
|
headers: this.authHeaders(),
|
|
@@ -7956,15 +8563,15 @@ var NksClient = class {
|
|
|
7956
8563
|
throw toNhnCloudCliError(err);
|
|
7957
8564
|
}
|
|
7958
8565
|
}
|
|
7959
|
-
async requestUuid(method,
|
|
7960
|
-
const raw = await this.requestJson(method,
|
|
8566
|
+
async requestUuid(method, path4, payload, errorMessage) {
|
|
8567
|
+
const raw = await this.requestJson(method, path4, payload);
|
|
7961
8568
|
if (!isNksUuidResponse(raw)) {
|
|
7962
8569
|
throw new NhnCloudCliError(errorMessage, EXIT_API_ERROR);
|
|
7963
8570
|
}
|
|
7964
8571
|
return raw;
|
|
7965
8572
|
}
|
|
7966
|
-
async requestNoBody(method,
|
|
7967
|
-
const url = `${this.nksEndpoint}${
|
|
8573
|
+
async requestNoBody(method, path4, payload) {
|
|
8574
|
+
const url = `${this.nksEndpoint}${path4}`;
|
|
7968
8575
|
try {
|
|
7969
8576
|
if (method === "delete") {
|
|
7970
8577
|
await import_ky14.default.delete(url, { headers: this.authHeaders(), retry: 0, timeout: DEFAULT_TIMEOUT_MS });
|
|
@@ -7975,8 +8582,8 @@ var NksClient = class {
|
|
|
7975
8582
|
throw toNhnCloudCliError(err);
|
|
7976
8583
|
}
|
|
7977
8584
|
}
|
|
7978
|
-
async requestJson(method,
|
|
7979
|
-
const url = `${this.nksEndpoint}${
|
|
8585
|
+
async requestJson(method, path4, payload) {
|
|
8586
|
+
const url = `${this.nksEndpoint}${path4}`;
|
|
7980
8587
|
try {
|
|
7981
8588
|
const options = { headers: this.authHeaders(), json: payload, retry: 0, timeout: DEFAULT_TIMEOUT_MS };
|
|
7982
8589
|
return method === "post" ? await import_ky14.default.post(url, options).json() : await import_ky14.default.patch(url, options).json();
|
|
@@ -8015,13 +8622,13 @@ async function resolveClusterUuid(client, cluster) {
|
|
|
8015
8622
|
}
|
|
8016
8623
|
return uuid;
|
|
8017
8624
|
}
|
|
8018
|
-
async function readJsonFile(
|
|
8625
|
+
async function readJsonFile(path4) {
|
|
8019
8626
|
let raw;
|
|
8020
8627
|
try {
|
|
8021
|
-
raw = await (0,
|
|
8628
|
+
raw = await (0, import_promises5.readFile)(path4, "utf-8");
|
|
8022
8629
|
} catch (err) {
|
|
8023
8630
|
const message = err instanceof Error ? err.message : String(err);
|
|
8024
|
-
throw new NhnCloudCliError(`JSON \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${
|
|
8631
|
+
throw new NhnCloudCliError(`JSON \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${path4} (${message})`, EXIT_PARAM_ERROR);
|
|
8025
8632
|
}
|
|
8026
8633
|
try {
|
|
8027
8634
|
const parsed = JSON.parse(raw);
|
|
@@ -8031,15 +8638,15 @@ async function readJsonFile(path5) {
|
|
|
8031
8638
|
return parsed;
|
|
8032
8639
|
} catch (err) {
|
|
8033
8640
|
const message = err instanceof Error ? err.message : String(err);
|
|
8034
|
-
throw new NhnCloudCliError(`JSON \uD30C\uC77C \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: ${
|
|
8641
|
+
throw new NhnCloudCliError(`JSON \uD30C\uC77C \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: ${path4} (${message})`, EXIT_PARAM_ERROR);
|
|
8035
8642
|
}
|
|
8036
8643
|
}
|
|
8037
|
-
async function readTextFile(
|
|
8644
|
+
async function readTextFile(path4) {
|
|
8038
8645
|
try {
|
|
8039
|
-
return await (0,
|
|
8646
|
+
return await (0, import_promises5.readFile)(path4, "utf-8");
|
|
8040
8647
|
} catch (err) {
|
|
8041
8648
|
const message = err instanceof Error ? err.message : String(err);
|
|
8042
|
-
throw new NhnCloudCliError(`\uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${
|
|
8649
|
+
throw new NhnCloudCliError(`\uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${path4} (${message})`, EXIT_PARAM_ERROR);
|
|
8043
8650
|
}
|
|
8044
8651
|
}
|
|
8045
8652
|
function parsePositiveInteger(value, optionName) {
|
|
@@ -8080,7 +8687,7 @@ var supportsCommand = new import_commander48.Command("supports").description("NK
|
|
|
8080
8687
|
});
|
|
8081
8688
|
|
|
8082
8689
|
// src/commands/nks/cluster.ts
|
|
8083
|
-
var
|
|
8690
|
+
var import_promises6 = require("fs/promises");
|
|
8084
8691
|
var import_commander49 = require("commander");
|
|
8085
8692
|
var import_chalk14 = __toESM(require("chalk"));
|
|
8086
8693
|
var listCommand8 = new import_commander49.Command("list").description("NKS \uD074\uB7EC\uC2A4\uD130 \uBAA9\uB85D\uC744 \uC870\uD68C\uD55C\uB2E4").option("--region <region>", "region override (\uAE30\uBCF8: iaas \uC790\uACA9\uC99D\uBA85\uC758 region)").option("--profile <name>", "\uC0AC\uC6A9\uD560 profile \uC774\uB984").action(async (_opts, cmd) => {
|
|
@@ -8171,18 +8778,18 @@ async function confirmDangerousAction(message, yes) {
|
|
|
8171
8778
|
}
|
|
8172
8779
|
return ok;
|
|
8173
8780
|
}
|
|
8174
|
-
async function writeKubeconfigFile(
|
|
8781
|
+
async function writeKubeconfigFile(path4, contents, force) {
|
|
8175
8782
|
try {
|
|
8176
|
-
await (0,
|
|
8783
|
+
await (0, import_promises6.writeFile)(path4, contents, {
|
|
8177
8784
|
encoding: "utf-8",
|
|
8178
8785
|
mode: 384,
|
|
8179
8786
|
flag: force ? "w" : "wx"
|
|
8180
8787
|
});
|
|
8181
|
-
await (0,
|
|
8788
|
+
await (0, import_promises6.chmod)(path4, 384);
|
|
8182
8789
|
} catch (err) {
|
|
8183
8790
|
if (err instanceof Error && "code" in err && err.code === "EEXIST") {
|
|
8184
8791
|
throw new NhnCloudCliError(
|
|
8185
|
-
`\uD30C\uC77C\uC774 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4: ${
|
|
8792
|
+
`\uD30C\uC77C\uC774 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4: ${path4}. \uB36E\uC5B4\uC4F0\uB824\uBA74 --force \uB97C \uC9C0\uC815\uD558\uC138\uC694.`,
|
|
8186
8793
|
EXIT_PARAM_ERROR
|
|
8187
8794
|
);
|
|
8188
8795
|
}
|
|
@@ -9001,9 +9608,9 @@ async function resolveNcsClient(opts) {
|
|
|
9001
9608
|
return { client: new NcsClient(accessToken, region, appKey), profileName };
|
|
9002
9609
|
}
|
|
9003
9610
|
function readJsonPayload(filePath) {
|
|
9004
|
-
let
|
|
9611
|
+
let stat4;
|
|
9005
9612
|
try {
|
|
9006
|
-
|
|
9613
|
+
stat4 = (0, import_node_fs9.statSync)(filePath);
|
|
9007
9614
|
} catch (err) {
|
|
9008
9615
|
const reason = err.code ?? (err instanceof Error ? err.message : String(err));
|
|
9009
9616
|
throw new NhnCloudCliError(
|
|
@@ -9011,12 +9618,12 @@ function readJsonPayload(filePath) {
|
|
|
9011
9618
|
EXIT_PARAM_ERROR
|
|
9012
9619
|
);
|
|
9013
9620
|
}
|
|
9014
|
-
if (!
|
|
9621
|
+
if (!stat4.isFile()) {
|
|
9015
9622
|
throw new NhnCloudCliError(`--file \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${filePath}`, EXIT_PARAM_ERROR);
|
|
9016
9623
|
}
|
|
9017
|
-
if (
|
|
9624
|
+
if (stat4.size > MAX_JSON_INPUT_BYTES) {
|
|
9018
9625
|
throw new NhnCloudCliError(
|
|
9019
|
-
`--file \uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${
|
|
9626
|
+
`--file \uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${stat4.size} \uBC14\uC774\uD2B8). JSON spec \uD55C\uB3C4 ${MAX_JSON_INPUT_BYTES} \uBC14\uC774\uD2B8.`,
|
|
9020
9627
|
EXIT_PARAM_ERROR
|
|
9021
9628
|
);
|
|
9022
9629
|
}
|
|
@@ -9747,7 +10354,7 @@ var malwareCommand = new import_commander54.Command("malware").description("NCS
|
|
|
9747
10354
|
var import_commander55 = require("commander");
|
|
9748
10355
|
|
|
9749
10356
|
// src/commands/apigateway/helpers.ts
|
|
9750
|
-
var
|
|
10357
|
+
var import_promises7 = require("fs/promises");
|
|
9751
10358
|
|
|
9752
10359
|
// src/services/apigateway/client.ts
|
|
9753
10360
|
var import_ky15 = __toESM(require("ky"));
|
|
@@ -10358,21 +10965,21 @@ function requireYes2(yes, operation) {
|
|
|
10358
10965
|
}
|
|
10359
10966
|
return true;
|
|
10360
10967
|
}
|
|
10361
|
-
async function readPluginConfigFile(
|
|
10968
|
+
async function readPluginConfigFile(path4) {
|
|
10362
10969
|
let fileStat;
|
|
10363
10970
|
try {
|
|
10364
|
-
fileStat = await (0,
|
|
10971
|
+
fileStat = await (0, import_promises7.stat)(path4);
|
|
10365
10972
|
} catch (error) {
|
|
10366
10973
|
const reason = fileErrorReason(error);
|
|
10367
10974
|
throw new NhnCloudCliError(
|
|
10368
|
-
`\uD50C\uB7EC\uADF8\uC778 \uC124\uC815 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${JSON.stringify(
|
|
10975
|
+
`\uD50C\uB7EC\uADF8\uC778 \uC124\uC815 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${JSON.stringify(path4)} (${JSON.stringify(reason)}).`,
|
|
10369
10976
|
EXIT_PARAM_ERROR
|
|
10370
10977
|
);
|
|
10371
10978
|
}
|
|
10372
10979
|
if (!fileStat.isFile()) {
|
|
10373
10980
|
const reason = fileStat.isDirectory() ? "EISDIR" : "EINVAL";
|
|
10374
10981
|
throw new NhnCloudCliError(
|
|
10375
|
-
`\uD50C\uB7EC\uADF8\uC778 \uC124\uC815 \uACBD\uB85C\uAC00 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${JSON.stringify(
|
|
10982
|
+
`\uD50C\uB7EC\uADF8\uC778 \uC124\uC815 \uACBD\uB85C\uAC00 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${JSON.stringify(path4)} (${reason}).`,
|
|
10376
10983
|
EXIT_PARAM_ERROR
|
|
10377
10984
|
);
|
|
10378
10985
|
}
|
|
@@ -10384,11 +10991,11 @@ async function readPluginConfigFile(path5) {
|
|
|
10384
10991
|
}
|
|
10385
10992
|
let raw;
|
|
10386
10993
|
try {
|
|
10387
|
-
raw = await (0,
|
|
10994
|
+
raw = await (0, import_promises7.readFile)(path4, "utf-8");
|
|
10388
10995
|
} catch (error) {
|
|
10389
10996
|
const reason = fileErrorReason(error);
|
|
10390
10997
|
throw new NhnCloudCliError(
|
|
10391
|
-
`\uD50C\uB7EC\uADF8\uC778 \uC124\uC815 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${JSON.stringify(
|
|
10998
|
+
`\uD50C\uB7EC\uADF8\uC778 \uC124\uC815 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${JSON.stringify(path4)} (${JSON.stringify(reason)}).`,
|
|
10392
10999
|
EXIT_PARAM_ERROR
|
|
10393
11000
|
);
|
|
10394
11001
|
}
|
|
@@ -10399,7 +11006,7 @@ async function readPluginConfigFile(path5) {
|
|
|
10399
11006
|
error instanceof Error ? error.message : String(error)
|
|
10400
11007
|
);
|
|
10401
11008
|
throw new NhnCloudCliError(
|
|
10402
|
-
`\uD50C\uB7EC\uADF8\uC778 \uC124\uC815 JSON \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: ${JSON.stringify(
|
|
11009
|
+
`\uD50C\uB7EC\uADF8\uC778 \uC124\uC815 JSON \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: ${JSON.stringify(path4)} (${reason}).`,
|
|
10403
11010
|
EXIT_PARAM_ERROR
|
|
10404
11011
|
);
|
|
10405
11012
|
}
|
|
@@ -10843,7 +11450,7 @@ var setMethodPluginCommand = addApiGatewayOptions(
|
|
|
10843
11450
|
var resourceCommand = new import_commander56.Command("resource").description("API Gateway resource \uC870\uD68C \uBC0F \uBCC0\uACBD \uBA85\uB839").addCommand(listCommand13).addCommand(parametersCommand).addCommand(responsesCommand).addCommand(setPathPluginCommand).addCommand(setMethodPluginCommand);
|
|
10844
11451
|
|
|
10845
11452
|
// src/commands/apigateway/stage.ts
|
|
10846
|
-
var
|
|
11453
|
+
var import_promises8 = require("fs/promises");
|
|
10847
11454
|
var import_commander58 = require("commander");
|
|
10848
11455
|
|
|
10849
11456
|
// src/commands/apigateway/deploy.ts
|
|
@@ -11050,9 +11657,9 @@ function fileErrorReason2(error) {
|
|
|
11050
11657
|
}
|
|
11051
11658
|
return error instanceof Error ? error.message : String(error);
|
|
11052
11659
|
}
|
|
11053
|
-
async function writeStageSwaggerFile(
|
|
11660
|
+
async function writeStageSwaggerFile(path4, swagger, force) {
|
|
11054
11661
|
try {
|
|
11055
|
-
await (0,
|
|
11662
|
+
await (0, import_promises8.writeFile)(path4, JSON.stringify(swagger, null, 2) + "\n", {
|
|
11056
11663
|
encoding: "utf-8",
|
|
11057
11664
|
flag: force ? "w" : "wx"
|
|
11058
11665
|
});
|
|
@@ -11060,7 +11667,7 @@ async function writeStageSwaggerFile(path5, swagger, force) {
|
|
|
11060
11667
|
const reason = fileErrorReason2(error);
|
|
11061
11668
|
const guidance = reason === "EEXIST" ? " \uB36E\uC5B4\uC4F0\uB824\uBA74 --force \uB97C \uC9C0\uC815\uD558\uC138\uC694." : "";
|
|
11062
11669
|
throw new NhnCloudCliError(
|
|
11063
|
-
`Swagger \uD30C\uC77C \uC800\uC7A5 \uC2E4\uD328: ${JSON.stringify(
|
|
11670
|
+
`Swagger \uD30C\uC77C \uC800\uC7A5 \uC2E4\uD328: ${JSON.stringify(path4)} (${JSON.stringify(reason)}).${guidance}`,
|
|
11064
11671
|
EXIT_PARAM_ERROR
|
|
11065
11672
|
);
|
|
11066
11673
|
}
|
|
@@ -11394,10 +12001,10 @@ var SkmClient = class {
|
|
|
11394
12001
|
* 요청을 보내고 봉투 형태인지만 확인해 반환한다. 성공 판정은 호출부가 한다.
|
|
11395
12002
|
* 쓰기 요청도 중복 실행을 막으려고 재시도하지 않는다.
|
|
11396
12003
|
*/
|
|
11397
|
-
async send(method,
|
|
12004
|
+
async send(method, path4, options) {
|
|
11398
12005
|
let response;
|
|
11399
12006
|
try {
|
|
11400
|
-
response = await import_ky16.default[method](`${this.baseUrl}${
|
|
12007
|
+
response = await import_ky16.default[method](`${this.baseUrl}${path4}`, {
|
|
11401
12008
|
headers: this.headers,
|
|
11402
12009
|
...options,
|
|
11403
12010
|
retry: 0,
|
|
@@ -11415,8 +12022,8 @@ var SkmClient = class {
|
|
|
11415
12022
|
* 요청을 보내고 봉투를 벗긴 뒤 body 또는 body[field] 를 가드로 검사해 반환한다.
|
|
11416
12023
|
* field 가 null 이면 body 전체를 검사한다.
|
|
11417
12024
|
*/
|
|
11418
|
-
async request(method,
|
|
11419
|
-
const body = unwrap(await this.send(method,
|
|
12025
|
+
async request(method, path4, field, guard, options = {}) {
|
|
12026
|
+
const body = unwrap(await this.send(method, path4, options));
|
|
11420
12027
|
const value = field === null ? body : isRecord4(body) ? body[field] : void 0;
|
|
11421
12028
|
if (!guard(value)) {
|
|
11422
12029
|
throw new NhnCloudCliError(`Secure Key Manager \uC751\uB2F5 \uD615\uC2DD \uC624\uB958: ${field ?? "body"}`, EXIT_API_ERROR);
|
|
@@ -11427,8 +12034,8 @@ var SkmClient = class {
|
|
|
11427
12034
|
* body 가 null 이거나 없는 응답(키 저장소 수정·삭제)은 검사할 필드가 없어 헤더만 본다 (ADR-040).
|
|
11428
12035
|
* isSuccessful 이 false 면 unwrapHeader 가 NhnEnvelopeError 를 던진다.
|
|
11429
12036
|
*/
|
|
11430
|
-
async requestHeaderOnly(method,
|
|
11431
|
-
unwrapHeader(await this.send(method,
|
|
12037
|
+
async requestHeaderOnly(method, path4, options = {}) {
|
|
12038
|
+
unwrapHeader(await this.send(method, path4, options));
|
|
11432
12039
|
}
|
|
11433
12040
|
keyPath(prefix, keyId, action) {
|
|
11434
12041
|
return `/${prefix}/${encodeURIComponent(keyId)}/${action}`;
|
|
@@ -11476,12 +12083,12 @@ var SkmClient = class {
|
|
|
11476
12083
|
return this.request("get", `/keystores/${keyStoreId}/keys/${encodeURIComponent(keyId)}`, null, isSkmKey);
|
|
11477
12084
|
}
|
|
11478
12085
|
listAuths(keyStoreId, type) {
|
|
11479
|
-
const { path:
|
|
11480
|
-
return this.request("get", `/keystores/${keyStoreId}/${
|
|
12086
|
+
const { path: path4, field } = AUTH_PATHS[type];
|
|
12087
|
+
return this.request("get", `/keystores/${keyStoreId}/${path4}`, field, arrayOf(isString));
|
|
11481
12088
|
}
|
|
11482
12089
|
getAuth(keyStoreId, type, value) {
|
|
11483
|
-
const { path:
|
|
11484
|
-
return this.request("get", `/keystores/${keyStoreId}/${
|
|
12090
|
+
const { path: path4, field } = AUTH_PATHS[type];
|
|
12091
|
+
return this.request("get", `/keystores/${keyStoreId}/${path4}`, field, arrayOf(isSkmAuthDetail), {
|
|
11485
12092
|
searchParams: { value }
|
|
11486
12093
|
});
|
|
11487
12094
|
}
|
|
@@ -11845,17 +12452,17 @@ function assertWithinLimit(size, spec) {
|
|
|
11845
12452
|
}
|
|
11846
12453
|
}
|
|
11847
12454
|
function readInputFile(file, spec) {
|
|
11848
|
-
let
|
|
12455
|
+
let stat4;
|
|
11849
12456
|
try {
|
|
11850
|
-
|
|
12457
|
+
stat4 = (0, import_node_fs10.statSync)(file);
|
|
11851
12458
|
} catch (e) {
|
|
11852
12459
|
const reason = e.code ?? (e instanceof Error ? e.message : String(e));
|
|
11853
12460
|
throw new NhnCloudCliError(`${spec.label} \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${file} (${reason})`, EXIT_PARAM_ERROR);
|
|
11854
12461
|
}
|
|
11855
|
-
if (!
|
|
12462
|
+
if (!stat4.isFile()) {
|
|
11856
12463
|
throw new NhnCloudCliError(`${spec.label} \uD30C\uC77C\uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${file}`, EXIT_PARAM_ERROR);
|
|
11857
12464
|
}
|
|
11858
|
-
assertWithinLimit(
|
|
12465
|
+
assertWithinLimit(stat4.size, spec);
|
|
11859
12466
|
return (0, import_node_fs10.readFileSync)(file);
|
|
11860
12467
|
}
|
|
11861
12468
|
function readStdin(stdin, spec) {
|
|
@@ -12747,8 +13354,8 @@ var LoadBalancerClient = class {
|
|
|
12747
13354
|
}
|
|
12748
13355
|
return raw;
|
|
12749
13356
|
}
|
|
12750
|
-
async getJson(
|
|
12751
|
-
const url = `${this.endpoint}${
|
|
13357
|
+
async getJson(path4, searchParams) {
|
|
13358
|
+
const url = `${this.endpoint}${path4}`;
|
|
12752
13359
|
try {
|
|
12753
13360
|
return await import_ky17.default.get(url, {
|
|
12754
13361
|
headers: this.authHeaders(),
|
|
@@ -12760,8 +13367,8 @@ var LoadBalancerClient = class {
|
|
|
12760
13367
|
throw toNhnCloudCliError(error);
|
|
12761
13368
|
}
|
|
12762
13369
|
}
|
|
12763
|
-
async postJson(
|
|
12764
|
-
const url = `${this.endpoint}${
|
|
13370
|
+
async postJson(path4, json) {
|
|
13371
|
+
const url = `${this.endpoint}${path4}`;
|
|
12765
13372
|
try {
|
|
12766
13373
|
return await import_ky17.default.post(url, {
|
|
12767
13374
|
headers: this.authHeaders(),
|
|
@@ -12773,8 +13380,8 @@ var LoadBalancerClient = class {
|
|
|
12773
13380
|
throw toNhnCloudCliError(error);
|
|
12774
13381
|
}
|
|
12775
13382
|
}
|
|
12776
|
-
async putJson(
|
|
12777
|
-
const url = `${this.endpoint}${
|
|
13383
|
+
async putJson(path4, json) {
|
|
13384
|
+
const url = `${this.endpoint}${path4}`;
|
|
12778
13385
|
try {
|
|
12779
13386
|
return await import_ky17.default.put(url, {
|
|
12780
13387
|
headers: this.authHeaders(),
|
|
@@ -12786,8 +13393,8 @@ var LoadBalancerClient = class {
|
|
|
12786
13393
|
throw toNhnCloudCliError(error);
|
|
12787
13394
|
}
|
|
12788
13395
|
}
|
|
12789
|
-
async deleteNoContent(
|
|
12790
|
-
const url = `${this.endpoint}${
|
|
13396
|
+
async deleteNoContent(path4) {
|
|
13397
|
+
const url = `${this.endpoint}${path4}`;
|
|
12791
13398
|
try {
|
|
12792
13399
|
await import_ky17.default.delete(url, {
|
|
12793
13400
|
headers: this.authHeaders(),
|