harnessed 3.9.17 → 3.9.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +218 -46
- package/dist/cli.mjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/messages/en.json +16 -2
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawnSync, spawn, execSync } from 'child_process';
|
|
3
3
|
import { existsSync, mkdirSync, renameSync, writeFileSync, readFileSync, readdirSync } from 'fs';
|
|
4
|
-
import { join, dirname, resolve, relative } from 'path';
|
|
4
|
+
import { join, dirname, resolve, sep, relative } from 'path';
|
|
5
5
|
import { homedir } from 'os';
|
|
6
6
|
import { readFile, readdir, unlink, writeFile, stat, rm, cp, mkdir, access, rename } from 'fs/promises';
|
|
7
7
|
import { Type } from '@sinclair/typebox';
|
|
@@ -1218,7 +1218,7 @@ var init_auto_install = __esm({
|
|
|
1218
1218
|
|
|
1219
1219
|
// package.json
|
|
1220
1220
|
var package_default = {
|
|
1221
|
-
version: "3.9.
|
|
1221
|
+
version: "3.9.19"};
|
|
1222
1222
|
|
|
1223
1223
|
// src/manifest/errors.ts
|
|
1224
1224
|
function instancePathToKeyPath(instancePath) {
|
|
@@ -2057,9 +2057,9 @@ function redactRecord(r) {
|
|
|
2057
2057
|
}
|
|
2058
2058
|
function renderHumanTable(records) {
|
|
2059
2059
|
const header = `${"ts".padEnd(19)} | ${"phase".padEnd(6)} | ${"category".padEnd(11)} | ${"matched_rule_id".padEnd(20)} | outcome`;
|
|
2060
|
-
const
|
|
2060
|
+
const sep2 = `${"-".repeat(19)}-+-${"-".repeat(6)}-+-${"-".repeat(11)}-+-${"-".repeat(20)}-+--------`;
|
|
2061
2061
|
console.log(header);
|
|
2062
|
-
console.log(
|
|
2062
|
+
console.log(sep2);
|
|
2063
2063
|
for (const r of records) {
|
|
2064
2064
|
const ts = r.ts.slice(0, 19);
|
|
2065
2065
|
const phase = r.phase.padEnd(6);
|
|
@@ -2069,7 +2069,7 @@ function renderHumanTable(records) {
|
|
|
2069
2069
|
}
|
|
2070
2070
|
}
|
|
2071
2071
|
function pipeToJq(filterExpr, lines) {
|
|
2072
|
-
return new Promise((
|
|
2072
|
+
return new Promise((resolve14, reject) => {
|
|
2073
2073
|
const child = spawn("jq", [filterExpr], {
|
|
2074
2074
|
stdio: ["pipe", "inherit", "inherit"],
|
|
2075
2075
|
windowsHide: true
|
|
@@ -2078,12 +2078,12 @@ function pipeToJq(filterExpr, lines) {
|
|
|
2078
2078
|
const e = err2;
|
|
2079
2079
|
if (e.code === "ENOENT") {
|
|
2080
2080
|
console.error(t("audit_log.jq_missing"));
|
|
2081
|
-
|
|
2081
|
+
resolve14(1);
|
|
2082
2082
|
} else {
|
|
2083
2083
|
reject(err2);
|
|
2084
2084
|
}
|
|
2085
2085
|
});
|
|
2086
|
-
child.on("close", (code) =>
|
|
2086
|
+
child.on("close", (code) => resolve14(code ?? 0));
|
|
2087
2087
|
child.stdin.write(lines.join("\n"));
|
|
2088
2088
|
child.stdin.end();
|
|
2089
2089
|
});
|
|
@@ -2740,10 +2740,10 @@ async function spawnCmd(ctx, cmd, args, timeoutMs) {
|
|
|
2740
2740
|
child.stderr?.setEncoding("utf8").on("data", (chunk) => {
|
|
2741
2741
|
stderr += chunk;
|
|
2742
2742
|
});
|
|
2743
|
-
return await new Promise((
|
|
2743
|
+
return await new Promise((resolve14) => {
|
|
2744
2744
|
const timer = setTimeout(() => {
|
|
2745
2745
|
child.kill("SIGKILL");
|
|
2746
|
-
|
|
2746
|
+
resolve14({
|
|
2747
2747
|
ok: false,
|
|
2748
2748
|
phase: "spawn",
|
|
2749
2749
|
error: {
|
|
@@ -2758,7 +2758,7 @@ async function spawnCmd(ctx, cmd, args, timeoutMs) {
|
|
|
2758
2758
|
}, effectiveTimeoutMs);
|
|
2759
2759
|
child.on("error", (err2) => {
|
|
2760
2760
|
clearTimeout(timer);
|
|
2761
|
-
|
|
2761
|
+
resolve14({
|
|
2762
2762
|
ok: false,
|
|
2763
2763
|
phase: "spawn",
|
|
2764
2764
|
error: {
|
|
@@ -2773,7 +2773,7 @@ async function spawnCmd(ctx, cmd, args, timeoutMs) {
|
|
|
2773
2773
|
});
|
|
2774
2774
|
child.on("close", (code) => {
|
|
2775
2775
|
clearTimeout(timer);
|
|
2776
|
-
|
|
2776
|
+
resolve14({ ok: true, exitCode: code ?? -1, stdout: stdout2, stderr });
|
|
2777
2777
|
});
|
|
2778
2778
|
});
|
|
2779
2779
|
}
|
|
@@ -2801,10 +2801,25 @@ function extractGitCloneTarget(cmd) {
|
|
|
2801
2801
|
if (dest.startsWith("/") || /^[A-Z]:[\\/]/i.test(dest)) return dest;
|
|
2802
2802
|
return null;
|
|
2803
2803
|
}
|
|
2804
|
+
var INSTALLED_INDICATORS = {
|
|
2805
|
+
gsd: ["gsd-progress", "gsd-plan-phase"],
|
|
2806
|
+
"mattpocock-skills": ["diagnose", "tdd", "zoom-out"]
|
|
2807
|
+
};
|
|
2804
2808
|
async function detectNative(ctx) {
|
|
2805
2809
|
const method = ctx.manifest.spec.install.method;
|
|
2806
2810
|
const cmd = ctx.manifest.spec.install.cmd;
|
|
2807
2811
|
const name = ctx.manifest.metadata.name;
|
|
2812
|
+
const indicators = INSTALLED_INDICATORS[name];
|
|
2813
|
+
if (indicators) {
|
|
2814
|
+
for (const ind of indicators) {
|
|
2815
|
+
const dir = join(homedir(), ".claude", "skills", ind);
|
|
2816
|
+
try {
|
|
2817
|
+
await access(dir);
|
|
2818
|
+
return true;
|
|
2819
|
+
} catch {
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
}
|
|
2808
2823
|
if (method === "cc-plugin-marketplace") {
|
|
2809
2824
|
const m = cmd.match(/(?:claude\s+)?plugin\s+install\s+(\S+)/i);
|
|
2810
2825
|
const pluginName = m?.[1]?.split("@")[0] ?? name;
|
|
@@ -2871,7 +2886,7 @@ async function isAlreadyInstalled(ctx, opts = {}) {
|
|
|
2871
2886
|
// src/installers/ccPluginMarketplace.ts
|
|
2872
2887
|
init_readClaudeConfig();
|
|
2873
2888
|
function runArgs(claudeArgs, cwd, timeoutMs = 15e3) {
|
|
2874
|
-
return new Promise((
|
|
2889
|
+
return new Promise((resolve14) => {
|
|
2875
2890
|
const isWin = process.platform === "win32";
|
|
2876
2891
|
const child = isWin ? spawn("cmd.exe", ["/c", "claude", ...claudeArgs], { cwd, windowsHide: true }) : spawn("claude", claudeArgs, { cwd, shell: false });
|
|
2877
2892
|
let stderr = "";
|
|
@@ -2880,15 +2895,15 @@ function runArgs(claudeArgs, cwd, timeoutMs = 15e3) {
|
|
|
2880
2895
|
});
|
|
2881
2896
|
const timer = setTimeout(() => {
|
|
2882
2897
|
child.kill("SIGKILL");
|
|
2883
|
-
|
|
2898
|
+
resolve14({ exitCode: -1, stderr: `${stderr}[timeout after ${timeoutMs}ms]` });
|
|
2884
2899
|
}, timeoutMs);
|
|
2885
2900
|
child.on("error", (e) => {
|
|
2886
2901
|
clearTimeout(timer);
|
|
2887
|
-
|
|
2902
|
+
resolve14({ exitCode: -1, stderr: `${stderr}${e.message}` });
|
|
2888
2903
|
});
|
|
2889
2904
|
child.on("close", (code) => {
|
|
2890
2905
|
clearTimeout(timer);
|
|
2891
|
-
|
|
2906
|
+
resolve14({ exitCode: code ?? -1, stderr });
|
|
2892
2907
|
});
|
|
2893
2908
|
});
|
|
2894
2909
|
}
|
|
@@ -3034,7 +3049,7 @@ ${newEntry}
|
|
|
3034
3049
|
return { ok: true, backupId: bk.backupId, appliedFiles: [settingsFile] };
|
|
3035
3050
|
};
|
|
3036
3051
|
function gitRevParseHead(cwd, timeoutMs = 1e4) {
|
|
3037
|
-
return new Promise((
|
|
3052
|
+
return new Promise((resolve14) => {
|
|
3038
3053
|
const isWin = process.platform === "win32";
|
|
3039
3054
|
const child = isWin ? spawn("cmd.exe", ["/c", "git", "rev-parse", "HEAD"], { cwd, windowsHide: true }) : spawn("git", ["rev-parse", "HEAD"], { cwd, shell: false });
|
|
3040
3055
|
let stdout2 = "";
|
|
@@ -3043,15 +3058,15 @@ function gitRevParseHead(cwd, timeoutMs = 1e4) {
|
|
|
3043
3058
|
});
|
|
3044
3059
|
const timer = setTimeout(() => {
|
|
3045
3060
|
child.kill("SIGKILL");
|
|
3046
|
-
|
|
3061
|
+
resolve14({ sha: "", exit: -1 });
|
|
3047
3062
|
}, timeoutMs);
|
|
3048
3063
|
child.on("error", () => {
|
|
3049
3064
|
clearTimeout(timer);
|
|
3050
|
-
|
|
3065
|
+
resolve14({ sha: "", exit: -1 });
|
|
3051
3066
|
});
|
|
3052
3067
|
child.on("close", (code) => {
|
|
3053
3068
|
clearTimeout(timer);
|
|
3054
|
-
|
|
3069
|
+
resolve14({ sha: stdout2.trim(), exit: code ?? -1 });
|
|
3055
3070
|
});
|
|
3056
3071
|
});
|
|
3057
3072
|
}
|
|
@@ -6373,6 +6388,7 @@ function registerStatus(program2) {
|
|
|
6373
6388
|
}
|
|
6374
6389
|
});
|
|
6375
6390
|
}
|
|
6391
|
+
init_harnessedRoot();
|
|
6376
6392
|
init_path_guard();
|
|
6377
6393
|
|
|
6378
6394
|
// src/uninstallers/lib/runOrPreview.ts
|
|
@@ -6558,7 +6574,7 @@ var uninstallNpmCli = async (ctx) => {
|
|
|
6558
6574
|
const m = install.cmd.match(/npm\s+(?:install|i)\s+(?:-g\s+)?(\S+)/);
|
|
6559
6575
|
const pkg = m?.[1] ?? ctx.manifest.metadata.upstream.source;
|
|
6560
6576
|
const isWin = process.platform === "win32";
|
|
6561
|
-
const result = await new Promise((
|
|
6577
|
+
const result = await new Promise((resolve14) => {
|
|
6562
6578
|
const child = isWin ? spawn("cmd.exe", ["/c", "npm", "uninstall", "-g", pkg], { windowsHide: true }) : spawn("npm", ["uninstall", "-g", pkg], { shell: false });
|
|
6563
6579
|
let stderr = "";
|
|
6564
6580
|
child.stderr?.setEncoding("utf8").on("data", (c) => {
|
|
@@ -6566,15 +6582,15 @@ var uninstallNpmCli = async (ctx) => {
|
|
|
6566
6582
|
});
|
|
6567
6583
|
const timer = setTimeout(() => {
|
|
6568
6584
|
child.kill("SIGKILL");
|
|
6569
|
-
|
|
6585
|
+
resolve14({ exitCode: -1, stderr: `${stderr}[timeout]` });
|
|
6570
6586
|
}, 3e4);
|
|
6571
6587
|
child.on("error", (e) => {
|
|
6572
6588
|
clearTimeout(timer);
|
|
6573
|
-
|
|
6589
|
+
resolve14({ exitCode: -1, stderr: e.message });
|
|
6574
6590
|
});
|
|
6575
6591
|
child.on("close", (code) => {
|
|
6576
6592
|
clearTimeout(timer);
|
|
6577
|
-
|
|
6593
|
+
resolve14({ exitCode: code ?? -1, stderr });
|
|
6578
6594
|
});
|
|
6579
6595
|
});
|
|
6580
6596
|
if (result.exitCode !== 0) {
|
|
@@ -6616,21 +6632,177 @@ async function runUninstall(manifest, opts) {
|
|
|
6616
6632
|
}
|
|
6617
6633
|
|
|
6618
6634
|
// src/cli/uninstall.ts
|
|
6635
|
+
async function discoverCommandFiles(commandsDir) {
|
|
6636
|
+
const owned = [];
|
|
6637
|
+
let entries;
|
|
6638
|
+
try {
|
|
6639
|
+
entries = await readdir(commandsDir);
|
|
6640
|
+
} catch {
|
|
6641
|
+
return owned;
|
|
6642
|
+
}
|
|
6643
|
+
for (const entry of entries) {
|
|
6644
|
+
if (!entry.endsWith(".md")) continue;
|
|
6645
|
+
const p5 = join(commandsDir, entry);
|
|
6646
|
+
try {
|
|
6647
|
+
const content = await readFile(p5, "utf8");
|
|
6648
|
+
if (shouldOverwriteFile(content)) owned.push(p5);
|
|
6649
|
+
} catch {
|
|
6650
|
+
}
|
|
6651
|
+
}
|
|
6652
|
+
return owned;
|
|
6653
|
+
}
|
|
6654
|
+
async function checkSettingsEnv(settingsPath3) {
|
|
6655
|
+
try {
|
|
6656
|
+
const raw = await readFile(settingsPath3, "utf8");
|
|
6657
|
+
const data = JSON.parse(raw);
|
|
6658
|
+
const env = data.env ?? {};
|
|
6659
|
+
return {
|
|
6660
|
+
hasAgentTeams: "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS" in env,
|
|
6661
|
+
hasUserLang: "HARNESSED_USER_LANG" in env
|
|
6662
|
+
};
|
|
6663
|
+
} catch {
|
|
6664
|
+
return { hasAgentTeams: false, hasUserLang: false };
|
|
6665
|
+
}
|
|
6666
|
+
}
|
|
6667
|
+
async function removeSettingsEnv(settingsPath3) {
|
|
6668
|
+
const raw = await readFile(settingsPath3, "utf8");
|
|
6669
|
+
const data = JSON.parse(raw);
|
|
6670
|
+
const env = data.env ?? {};
|
|
6671
|
+
let changed = false;
|
|
6672
|
+
if ("CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS" in env) {
|
|
6673
|
+
delete env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS;
|
|
6674
|
+
changed = true;
|
|
6675
|
+
}
|
|
6676
|
+
if ("HARNESSED_USER_LANG" in env) {
|
|
6677
|
+
delete env.HARNESSED_USER_LANG;
|
|
6678
|
+
changed = true;
|
|
6679
|
+
}
|
|
6680
|
+
if (!changed) return false;
|
|
6681
|
+
if (Object.keys(env).length === 0) delete data.env;
|
|
6682
|
+
else data.env = env;
|
|
6683
|
+
await writeFile(settingsPath3, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
6684
|
+
return true;
|
|
6685
|
+
}
|
|
6686
|
+
async function runUnifiedUninstall(home, dryRun) {
|
|
6687
|
+
const commandsDir = join(home, ".claude", "commands");
|
|
6688
|
+
const skillsDir = join(home, ".claude", "skills");
|
|
6689
|
+
const settingsPath3 = join(home, ".claude", "settings.json");
|
|
6690
|
+
const harnessedRoot = getHarnessedRoot();
|
|
6691
|
+
const pkgRoot = getPackageRoot();
|
|
6692
|
+
let workflowNames = [];
|
|
6693
|
+
try {
|
|
6694
|
+
const wfEntries = await readdir(resolve(pkgRoot, "workflows"));
|
|
6695
|
+
const scanResult = await scanWorkflowsNested(resolve(pkgRoot, "workflows"), wfEntries);
|
|
6696
|
+
workflowNames = scanResult.workflows.map((w) => w.name);
|
|
6697
|
+
} catch {
|
|
6698
|
+
}
|
|
6699
|
+
const commandFiles = await discoverCommandFiles(commandsDir);
|
|
6700
|
+
const settingsEnv = await checkSettingsEnv(settingsPath3);
|
|
6701
|
+
const hasSettingsChanges = settingsEnv.hasAgentTeams || settingsEnv.hasUserLang;
|
|
6702
|
+
const skillDirs = [];
|
|
6703
|
+
for (const name of workflowNames) {
|
|
6704
|
+
const dir = join(skillsDir, name);
|
|
6705
|
+
try {
|
|
6706
|
+
await stat(dir);
|
|
6707
|
+
skillDirs.push(dir);
|
|
6708
|
+
} catch {
|
|
6709
|
+
}
|
|
6710
|
+
}
|
|
6711
|
+
const discoverable = commandFiles.length + skillDirs.length + (hasSettingsChanges ? 1 : 0);
|
|
6712
|
+
if (discoverable === 0) {
|
|
6713
|
+
console.log(t("uninstall.unified.nothing"));
|
|
6714
|
+
process.exit(0);
|
|
6715
|
+
}
|
|
6716
|
+
console.log(t("uninstall.unified.header"));
|
|
6717
|
+
if (commandFiles.length > 0)
|
|
6718
|
+
console.log(t("uninstall.unified.commands", { count: commandFiles.length }));
|
|
6719
|
+
if (skillDirs.length > 0) console.log(t("uninstall.unified.skills", { count: skillDirs.length }));
|
|
6720
|
+
if (hasSettingsChanges) console.log(t("uninstall.unified.settings"));
|
|
6721
|
+
console.log(t("uninstall.unified.state_dir"));
|
|
6722
|
+
console.log(t("uninstall.unified.upstream_note"));
|
|
6723
|
+
if (dryRun) {
|
|
6724
|
+
console.log(t("uninstall.unified.dry_run_hint"));
|
|
6725
|
+
process.exit(2);
|
|
6726
|
+
}
|
|
6727
|
+
const answer = await p.confirm({
|
|
6728
|
+
message: t("uninstall.unified.confirm"),
|
|
6729
|
+
initialValue: false
|
|
6730
|
+
});
|
|
6731
|
+
if (p.isCancel(answer) || answer === false) {
|
|
6732
|
+
console.error(t("uninstall.cancelled"));
|
|
6733
|
+
process.exit(2);
|
|
6734
|
+
}
|
|
6735
|
+
console.log(t("uninstall.unified.removing"));
|
|
6736
|
+
const failures = [];
|
|
6737
|
+
let removedCommands = 0;
|
|
6738
|
+
for (const path of commandFiles) {
|
|
6739
|
+
try {
|
|
6740
|
+
await rm(path, { force: true });
|
|
6741
|
+
removedCommands++;
|
|
6742
|
+
} catch (e) {
|
|
6743
|
+
failures.push(`${path}: ${e.message}`);
|
|
6744
|
+
}
|
|
6745
|
+
}
|
|
6746
|
+
let removedSkills = 0;
|
|
6747
|
+
for (const dir of skillDirs) {
|
|
6748
|
+
try {
|
|
6749
|
+
await rm(dir, { recursive: true, force: true });
|
|
6750
|
+
removedSkills++;
|
|
6751
|
+
} catch (e) {
|
|
6752
|
+
failures.push(`${dir}: ${e.message}`);
|
|
6753
|
+
}
|
|
6754
|
+
}
|
|
6755
|
+
let removedSettings = false;
|
|
6756
|
+
if (hasSettingsChanges) {
|
|
6757
|
+
try {
|
|
6758
|
+
removedSettings = await removeSettingsEnv(settingsPath3);
|
|
6759
|
+
} catch (e) {
|
|
6760
|
+
failures.push(`${settingsPath3}: ${e.message}`);
|
|
6761
|
+
}
|
|
6762
|
+
}
|
|
6763
|
+
const normalizedRoot = resolve(harnessedRoot);
|
|
6764
|
+
const claudeDir = join(home, ".claude");
|
|
6765
|
+
if (!normalizedRoot.startsWith(resolve(claudeDir) + sep)) {
|
|
6766
|
+
console.error(`error: state dir ${harnessedRoot} is not under ${claudeDir} \u2014 refusing`);
|
|
6767
|
+
process.exit(1);
|
|
6768
|
+
}
|
|
6769
|
+
let removedStateDir = false;
|
|
6770
|
+
try {
|
|
6771
|
+
await rm(harnessedRoot, { recursive: true, force: true });
|
|
6772
|
+
removedStateDir = true;
|
|
6773
|
+
} catch (e) {
|
|
6774
|
+
failures.push(`${harnessedRoot}: ${e.message}`);
|
|
6775
|
+
}
|
|
6776
|
+
if (removedCommands > 0)
|
|
6777
|
+
console.log(t("uninstall.unified.removed_commands", { count: removedCommands }));
|
|
6778
|
+
if (removedSkills > 0)
|
|
6779
|
+
console.log(t("uninstall.unified.removed_skills", { count: removedSkills }));
|
|
6780
|
+
if (removedSettings) console.log(t("uninstall.unified.removed_settings"));
|
|
6781
|
+
if (removedStateDir) console.log(t("uninstall.unified.removed_state_dir"));
|
|
6782
|
+
if (failures.length > 0) {
|
|
6783
|
+
console.error(t("uninstall.unified.partial_failure", { count: failures.length }));
|
|
6784
|
+
for (const f of failures) console.error(` ${f}`);
|
|
6785
|
+
}
|
|
6786
|
+
console.log(t("uninstall.unified.complete"));
|
|
6787
|
+
process.exit(0);
|
|
6788
|
+
}
|
|
6619
6789
|
function registerUninstall(program2) {
|
|
6620
|
-
program2.command("uninstall
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
process.exit(2);
|
|
6790
|
+
program2.command("uninstall [name]").description(
|
|
6791
|
+
"Uninstall an upstream by name, or remove all harnessed own files when no name given"
|
|
6792
|
+
).option("--dry-run", "preview only \u2014 do not delete files").action(async (name, raw) => {
|
|
6793
|
+
const dryRun = raw.dryRun === true;
|
|
6794
|
+
if (!name) {
|
|
6795
|
+
await runUnifiedUninstall(homedir(), dryRun);
|
|
6796
|
+
return;
|
|
6628
6797
|
}
|
|
6629
6798
|
const { resolveAlias: resolveAlias2 } = await Promise.resolve().then(() => (init_aliases(), aliases_exports));
|
|
6630
6799
|
const resolvedName = resolveAlias2(name) ?? name;
|
|
6631
6800
|
checkPathSafe(resolvedName);
|
|
6632
6801
|
const manifestPath = resolve(getPackageRoot(), `manifests/tools/${resolvedName}.yaml`);
|
|
6633
|
-
const skillPackPath = resolve(
|
|
6802
|
+
const skillPackPath = resolve(
|
|
6803
|
+
getPackageRoot(),
|
|
6804
|
+
`manifests/skill-packs/${resolvedName}.yaml`
|
|
6805
|
+
);
|
|
6634
6806
|
let yamlSrc;
|
|
6635
6807
|
let chosenPath = manifestPath;
|
|
6636
6808
|
try {
|
|
@@ -6652,25 +6824,25 @@ ${t("install.manifest_not_found.fix", { name: resolvedName })}`
|
|
|
6652
6824
|
for (const e of v.errors) console.error(`error: ${e.message} at ${e.path}`);
|
|
6653
6825
|
process.exit(1);
|
|
6654
6826
|
}
|
|
6655
|
-
const method = v.manifest.spec.install.method;
|
|
6656
|
-
const dryRun = raw.dryRun === true;
|
|
6657
6827
|
if (dryRun) {
|
|
6658
|
-
console.log(
|
|
6828
|
+
console.log(
|
|
6829
|
+
t("uninstall.dry_run.preview", {
|
|
6830
|
+
name: resolvedName,
|
|
6831
|
+
method: v.manifest.spec.install.method
|
|
6832
|
+
})
|
|
6833
|
+
);
|
|
6659
6834
|
console.log(t("uninstall.dry_run.run_hint"));
|
|
6660
6835
|
process.exit(2);
|
|
6661
6836
|
}
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
process.exit(2);
|
|
6670
|
-
}
|
|
6837
|
+
const answer = await p.confirm({
|
|
6838
|
+
message: t("uninstall.confirm.prompt", { name: resolvedName }),
|
|
6839
|
+
initialValue: false
|
|
6840
|
+
});
|
|
6841
|
+
if (p.isCancel(answer) || answer === false) {
|
|
6842
|
+
console.error(t("uninstall.cancelled"));
|
|
6843
|
+
process.exit(2);
|
|
6671
6844
|
}
|
|
6672
|
-
const
|
|
6673
|
-
const result = await runUninstall(v.manifest, opts);
|
|
6845
|
+
const result = await runUninstall(v.manifest, { apply: true, dryRun: false, yes: true });
|
|
6674
6846
|
if ("aborted" in result) {
|
|
6675
6847
|
console.error(t("install.aborted", { reason: result.reason }));
|
|
6676
6848
|
process.exit(2);
|