harnessed 3.9.17 → 3.9.18
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 +203 -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.18"};
|
|
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
|
}
|
|
@@ -2871,7 +2871,7 @@ async function isAlreadyInstalled(ctx, opts = {}) {
|
|
|
2871
2871
|
// src/installers/ccPluginMarketplace.ts
|
|
2872
2872
|
init_readClaudeConfig();
|
|
2873
2873
|
function runArgs(claudeArgs, cwd, timeoutMs = 15e3) {
|
|
2874
|
-
return new Promise((
|
|
2874
|
+
return new Promise((resolve14) => {
|
|
2875
2875
|
const isWin = process.platform === "win32";
|
|
2876
2876
|
const child = isWin ? spawn("cmd.exe", ["/c", "claude", ...claudeArgs], { cwd, windowsHide: true }) : spawn("claude", claudeArgs, { cwd, shell: false });
|
|
2877
2877
|
let stderr = "";
|
|
@@ -2880,15 +2880,15 @@ function runArgs(claudeArgs, cwd, timeoutMs = 15e3) {
|
|
|
2880
2880
|
});
|
|
2881
2881
|
const timer = setTimeout(() => {
|
|
2882
2882
|
child.kill("SIGKILL");
|
|
2883
|
-
|
|
2883
|
+
resolve14({ exitCode: -1, stderr: `${stderr}[timeout after ${timeoutMs}ms]` });
|
|
2884
2884
|
}, timeoutMs);
|
|
2885
2885
|
child.on("error", (e) => {
|
|
2886
2886
|
clearTimeout(timer);
|
|
2887
|
-
|
|
2887
|
+
resolve14({ exitCode: -1, stderr: `${stderr}${e.message}` });
|
|
2888
2888
|
});
|
|
2889
2889
|
child.on("close", (code) => {
|
|
2890
2890
|
clearTimeout(timer);
|
|
2891
|
-
|
|
2891
|
+
resolve14({ exitCode: code ?? -1, stderr });
|
|
2892
2892
|
});
|
|
2893
2893
|
});
|
|
2894
2894
|
}
|
|
@@ -3034,7 +3034,7 @@ ${newEntry}
|
|
|
3034
3034
|
return { ok: true, backupId: bk.backupId, appliedFiles: [settingsFile] };
|
|
3035
3035
|
};
|
|
3036
3036
|
function gitRevParseHead(cwd, timeoutMs = 1e4) {
|
|
3037
|
-
return new Promise((
|
|
3037
|
+
return new Promise((resolve14) => {
|
|
3038
3038
|
const isWin = process.platform === "win32";
|
|
3039
3039
|
const child = isWin ? spawn("cmd.exe", ["/c", "git", "rev-parse", "HEAD"], { cwd, windowsHide: true }) : spawn("git", ["rev-parse", "HEAD"], { cwd, shell: false });
|
|
3040
3040
|
let stdout2 = "";
|
|
@@ -3043,15 +3043,15 @@ function gitRevParseHead(cwd, timeoutMs = 1e4) {
|
|
|
3043
3043
|
});
|
|
3044
3044
|
const timer = setTimeout(() => {
|
|
3045
3045
|
child.kill("SIGKILL");
|
|
3046
|
-
|
|
3046
|
+
resolve14({ sha: "", exit: -1 });
|
|
3047
3047
|
}, timeoutMs);
|
|
3048
3048
|
child.on("error", () => {
|
|
3049
3049
|
clearTimeout(timer);
|
|
3050
|
-
|
|
3050
|
+
resolve14({ sha: "", exit: -1 });
|
|
3051
3051
|
});
|
|
3052
3052
|
child.on("close", (code) => {
|
|
3053
3053
|
clearTimeout(timer);
|
|
3054
|
-
|
|
3054
|
+
resolve14({ sha: stdout2.trim(), exit: code ?? -1 });
|
|
3055
3055
|
});
|
|
3056
3056
|
});
|
|
3057
3057
|
}
|
|
@@ -6373,6 +6373,7 @@ function registerStatus(program2) {
|
|
|
6373
6373
|
}
|
|
6374
6374
|
});
|
|
6375
6375
|
}
|
|
6376
|
+
init_harnessedRoot();
|
|
6376
6377
|
init_path_guard();
|
|
6377
6378
|
|
|
6378
6379
|
// src/uninstallers/lib/runOrPreview.ts
|
|
@@ -6558,7 +6559,7 @@ var uninstallNpmCli = async (ctx) => {
|
|
|
6558
6559
|
const m = install.cmd.match(/npm\s+(?:install|i)\s+(?:-g\s+)?(\S+)/);
|
|
6559
6560
|
const pkg = m?.[1] ?? ctx.manifest.metadata.upstream.source;
|
|
6560
6561
|
const isWin = process.platform === "win32";
|
|
6561
|
-
const result = await new Promise((
|
|
6562
|
+
const result = await new Promise((resolve14) => {
|
|
6562
6563
|
const child = isWin ? spawn("cmd.exe", ["/c", "npm", "uninstall", "-g", pkg], { windowsHide: true }) : spawn("npm", ["uninstall", "-g", pkg], { shell: false });
|
|
6563
6564
|
let stderr = "";
|
|
6564
6565
|
child.stderr?.setEncoding("utf8").on("data", (c) => {
|
|
@@ -6566,15 +6567,15 @@ var uninstallNpmCli = async (ctx) => {
|
|
|
6566
6567
|
});
|
|
6567
6568
|
const timer = setTimeout(() => {
|
|
6568
6569
|
child.kill("SIGKILL");
|
|
6569
|
-
|
|
6570
|
+
resolve14({ exitCode: -1, stderr: `${stderr}[timeout]` });
|
|
6570
6571
|
}, 3e4);
|
|
6571
6572
|
child.on("error", (e) => {
|
|
6572
6573
|
clearTimeout(timer);
|
|
6573
|
-
|
|
6574
|
+
resolve14({ exitCode: -1, stderr: e.message });
|
|
6574
6575
|
});
|
|
6575
6576
|
child.on("close", (code) => {
|
|
6576
6577
|
clearTimeout(timer);
|
|
6577
|
-
|
|
6578
|
+
resolve14({ exitCode: code ?? -1, stderr });
|
|
6578
6579
|
});
|
|
6579
6580
|
});
|
|
6580
6581
|
if (result.exitCode !== 0) {
|
|
@@ -6616,21 +6617,177 @@ async function runUninstall(manifest, opts) {
|
|
|
6616
6617
|
}
|
|
6617
6618
|
|
|
6618
6619
|
// src/cli/uninstall.ts
|
|
6620
|
+
async function discoverCommandFiles(commandsDir) {
|
|
6621
|
+
const owned = [];
|
|
6622
|
+
let entries;
|
|
6623
|
+
try {
|
|
6624
|
+
entries = await readdir(commandsDir);
|
|
6625
|
+
} catch {
|
|
6626
|
+
return owned;
|
|
6627
|
+
}
|
|
6628
|
+
for (const entry of entries) {
|
|
6629
|
+
if (!entry.endsWith(".md")) continue;
|
|
6630
|
+
const p5 = join(commandsDir, entry);
|
|
6631
|
+
try {
|
|
6632
|
+
const content = await readFile(p5, "utf8");
|
|
6633
|
+
if (shouldOverwriteFile(content)) owned.push(p5);
|
|
6634
|
+
} catch {
|
|
6635
|
+
}
|
|
6636
|
+
}
|
|
6637
|
+
return owned;
|
|
6638
|
+
}
|
|
6639
|
+
async function checkSettingsEnv(settingsPath3) {
|
|
6640
|
+
try {
|
|
6641
|
+
const raw = await readFile(settingsPath3, "utf8");
|
|
6642
|
+
const data = JSON.parse(raw);
|
|
6643
|
+
const env = data.env ?? {};
|
|
6644
|
+
return {
|
|
6645
|
+
hasAgentTeams: "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS" in env,
|
|
6646
|
+
hasUserLang: "HARNESSED_USER_LANG" in env
|
|
6647
|
+
};
|
|
6648
|
+
} catch {
|
|
6649
|
+
return { hasAgentTeams: false, hasUserLang: false };
|
|
6650
|
+
}
|
|
6651
|
+
}
|
|
6652
|
+
async function removeSettingsEnv(settingsPath3) {
|
|
6653
|
+
const raw = await readFile(settingsPath3, "utf8");
|
|
6654
|
+
const data = JSON.parse(raw);
|
|
6655
|
+
const env = data.env ?? {};
|
|
6656
|
+
let changed = false;
|
|
6657
|
+
if ("CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS" in env) {
|
|
6658
|
+
delete env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS;
|
|
6659
|
+
changed = true;
|
|
6660
|
+
}
|
|
6661
|
+
if ("HARNESSED_USER_LANG" in env) {
|
|
6662
|
+
delete env.HARNESSED_USER_LANG;
|
|
6663
|
+
changed = true;
|
|
6664
|
+
}
|
|
6665
|
+
if (!changed) return false;
|
|
6666
|
+
if (Object.keys(env).length === 0) delete data.env;
|
|
6667
|
+
else data.env = env;
|
|
6668
|
+
await writeFile(settingsPath3, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
6669
|
+
return true;
|
|
6670
|
+
}
|
|
6671
|
+
async function runUnifiedUninstall(home, dryRun) {
|
|
6672
|
+
const commandsDir = join(home, ".claude", "commands");
|
|
6673
|
+
const skillsDir = join(home, ".claude", "skills");
|
|
6674
|
+
const settingsPath3 = join(home, ".claude", "settings.json");
|
|
6675
|
+
const harnessedRoot = getHarnessedRoot();
|
|
6676
|
+
const pkgRoot = getPackageRoot();
|
|
6677
|
+
let workflowNames = [];
|
|
6678
|
+
try {
|
|
6679
|
+
const wfEntries = await readdir(resolve(pkgRoot, "workflows"));
|
|
6680
|
+
const scanResult = await scanWorkflowsNested(resolve(pkgRoot, "workflows"), wfEntries);
|
|
6681
|
+
workflowNames = scanResult.workflows.map((w) => w.name);
|
|
6682
|
+
} catch {
|
|
6683
|
+
}
|
|
6684
|
+
const commandFiles = await discoverCommandFiles(commandsDir);
|
|
6685
|
+
const settingsEnv = await checkSettingsEnv(settingsPath3);
|
|
6686
|
+
const hasSettingsChanges = settingsEnv.hasAgentTeams || settingsEnv.hasUserLang;
|
|
6687
|
+
const skillDirs = [];
|
|
6688
|
+
for (const name of workflowNames) {
|
|
6689
|
+
const dir = join(skillsDir, name);
|
|
6690
|
+
try {
|
|
6691
|
+
await stat(dir);
|
|
6692
|
+
skillDirs.push(dir);
|
|
6693
|
+
} catch {
|
|
6694
|
+
}
|
|
6695
|
+
}
|
|
6696
|
+
const discoverable = commandFiles.length + skillDirs.length + (hasSettingsChanges ? 1 : 0);
|
|
6697
|
+
if (discoverable === 0) {
|
|
6698
|
+
console.log(t("uninstall.unified.nothing"));
|
|
6699
|
+
process.exit(0);
|
|
6700
|
+
}
|
|
6701
|
+
console.log(t("uninstall.unified.header"));
|
|
6702
|
+
if (commandFiles.length > 0)
|
|
6703
|
+
console.log(t("uninstall.unified.commands", { count: commandFiles.length }));
|
|
6704
|
+
if (skillDirs.length > 0) console.log(t("uninstall.unified.skills", { count: skillDirs.length }));
|
|
6705
|
+
if (hasSettingsChanges) console.log(t("uninstall.unified.settings"));
|
|
6706
|
+
console.log(t("uninstall.unified.state_dir"));
|
|
6707
|
+
console.log(t("uninstall.unified.upstream_note"));
|
|
6708
|
+
if (dryRun) {
|
|
6709
|
+
console.log(t("uninstall.unified.dry_run_hint"));
|
|
6710
|
+
process.exit(2);
|
|
6711
|
+
}
|
|
6712
|
+
const answer = await p.confirm({
|
|
6713
|
+
message: t("uninstall.unified.confirm"),
|
|
6714
|
+
initialValue: false
|
|
6715
|
+
});
|
|
6716
|
+
if (p.isCancel(answer) || answer === false) {
|
|
6717
|
+
console.error(t("uninstall.cancelled"));
|
|
6718
|
+
process.exit(2);
|
|
6719
|
+
}
|
|
6720
|
+
console.log(t("uninstall.unified.removing"));
|
|
6721
|
+
const failures = [];
|
|
6722
|
+
let removedCommands = 0;
|
|
6723
|
+
for (const path of commandFiles) {
|
|
6724
|
+
try {
|
|
6725
|
+
await rm(path, { force: true });
|
|
6726
|
+
removedCommands++;
|
|
6727
|
+
} catch (e) {
|
|
6728
|
+
failures.push(`${path}: ${e.message}`);
|
|
6729
|
+
}
|
|
6730
|
+
}
|
|
6731
|
+
let removedSkills = 0;
|
|
6732
|
+
for (const dir of skillDirs) {
|
|
6733
|
+
try {
|
|
6734
|
+
await rm(dir, { recursive: true, force: true });
|
|
6735
|
+
removedSkills++;
|
|
6736
|
+
} catch (e) {
|
|
6737
|
+
failures.push(`${dir}: ${e.message}`);
|
|
6738
|
+
}
|
|
6739
|
+
}
|
|
6740
|
+
let removedSettings = false;
|
|
6741
|
+
if (hasSettingsChanges) {
|
|
6742
|
+
try {
|
|
6743
|
+
removedSettings = await removeSettingsEnv(settingsPath3);
|
|
6744
|
+
} catch (e) {
|
|
6745
|
+
failures.push(`${settingsPath3}: ${e.message}`);
|
|
6746
|
+
}
|
|
6747
|
+
}
|
|
6748
|
+
const normalizedRoot = resolve(harnessedRoot);
|
|
6749
|
+
const claudeDir = join(home, ".claude");
|
|
6750
|
+
if (!normalizedRoot.startsWith(resolve(claudeDir) + sep)) {
|
|
6751
|
+
console.error(`error: state dir ${harnessedRoot} is not under ${claudeDir} \u2014 refusing`);
|
|
6752
|
+
process.exit(1);
|
|
6753
|
+
}
|
|
6754
|
+
let removedStateDir = false;
|
|
6755
|
+
try {
|
|
6756
|
+
await rm(harnessedRoot, { recursive: true, force: true });
|
|
6757
|
+
removedStateDir = true;
|
|
6758
|
+
} catch (e) {
|
|
6759
|
+
failures.push(`${harnessedRoot}: ${e.message}`);
|
|
6760
|
+
}
|
|
6761
|
+
if (removedCommands > 0)
|
|
6762
|
+
console.log(t("uninstall.unified.removed_commands", { count: removedCommands }));
|
|
6763
|
+
if (removedSkills > 0)
|
|
6764
|
+
console.log(t("uninstall.unified.removed_skills", { count: removedSkills }));
|
|
6765
|
+
if (removedSettings) console.log(t("uninstall.unified.removed_settings"));
|
|
6766
|
+
if (removedStateDir) console.log(t("uninstall.unified.removed_state_dir"));
|
|
6767
|
+
if (failures.length > 0) {
|
|
6768
|
+
console.error(t("uninstall.unified.partial_failure", { count: failures.length }));
|
|
6769
|
+
for (const f of failures) console.error(` ${f}`);
|
|
6770
|
+
}
|
|
6771
|
+
console.log(t("uninstall.unified.complete"));
|
|
6772
|
+
process.exit(0);
|
|
6773
|
+
}
|
|
6619
6774
|
function registerUninstall(program2) {
|
|
6620
|
-
program2.command("uninstall
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
process.exit(2);
|
|
6775
|
+
program2.command("uninstall [name]").description(
|
|
6776
|
+
"Uninstall an upstream by name, or remove all harnessed own files when no name given"
|
|
6777
|
+
).option("--dry-run", "preview only \u2014 do not delete files").action(async (name, raw) => {
|
|
6778
|
+
const dryRun = raw.dryRun === true;
|
|
6779
|
+
if (!name) {
|
|
6780
|
+
await runUnifiedUninstall(homedir(), dryRun);
|
|
6781
|
+
return;
|
|
6628
6782
|
}
|
|
6629
6783
|
const { resolveAlias: resolveAlias2 } = await Promise.resolve().then(() => (init_aliases(), aliases_exports));
|
|
6630
6784
|
const resolvedName = resolveAlias2(name) ?? name;
|
|
6631
6785
|
checkPathSafe(resolvedName);
|
|
6632
6786
|
const manifestPath = resolve(getPackageRoot(), `manifests/tools/${resolvedName}.yaml`);
|
|
6633
|
-
const skillPackPath = resolve(
|
|
6787
|
+
const skillPackPath = resolve(
|
|
6788
|
+
getPackageRoot(),
|
|
6789
|
+
`manifests/skill-packs/${resolvedName}.yaml`
|
|
6790
|
+
);
|
|
6634
6791
|
let yamlSrc;
|
|
6635
6792
|
let chosenPath = manifestPath;
|
|
6636
6793
|
try {
|
|
@@ -6652,25 +6809,25 @@ ${t("install.manifest_not_found.fix", { name: resolvedName })}`
|
|
|
6652
6809
|
for (const e of v.errors) console.error(`error: ${e.message} at ${e.path}`);
|
|
6653
6810
|
process.exit(1);
|
|
6654
6811
|
}
|
|
6655
|
-
const method = v.manifest.spec.install.method;
|
|
6656
|
-
const dryRun = raw.dryRun === true;
|
|
6657
6812
|
if (dryRun) {
|
|
6658
|
-
console.log(
|
|
6813
|
+
console.log(
|
|
6814
|
+
t("uninstall.dry_run.preview", {
|
|
6815
|
+
name: resolvedName,
|
|
6816
|
+
method: v.manifest.spec.install.method
|
|
6817
|
+
})
|
|
6818
|
+
);
|
|
6659
6819
|
console.log(t("uninstall.dry_run.run_hint"));
|
|
6660
6820
|
process.exit(2);
|
|
6661
6821
|
}
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
process.exit(2);
|
|
6670
|
-
}
|
|
6822
|
+
const answer = await p.confirm({
|
|
6823
|
+
message: t("uninstall.confirm.prompt", { name: resolvedName }),
|
|
6824
|
+
initialValue: false
|
|
6825
|
+
});
|
|
6826
|
+
if (p.isCancel(answer) || answer === false) {
|
|
6827
|
+
console.error(t("uninstall.cancelled"));
|
|
6828
|
+
process.exit(2);
|
|
6671
6829
|
}
|
|
6672
|
-
const
|
|
6673
|
-
const result = await runUninstall(v.manifest, opts);
|
|
6830
|
+
const result = await runUninstall(v.manifest, { apply: true, dryRun: false, yes: true });
|
|
6674
6831
|
if ("aborted" in result) {
|
|
6675
6832
|
console.error(t("install.aborted", { reason: result.reason }));
|
|
6676
6833
|
process.exit(2);
|