@detergent-software/atk 7.12.0-dev.3 → 7.12.0-dev.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/commands/audit.d.ts.map +1 -1
- package/build/commands/audit.js +36 -5
- package/build/commands/audit.js.map +1 -1
- package/build/commands/install.d.ts.map +1 -1
- package/build/commands/install.js +24 -9
- package/build/commands/install.js.map +1 -1
- package/build/commands/list.js +13 -1
- package/build/commands/list.js.map +1 -1
- package/build/commands/setup.d.ts +2 -2
- package/build/commands/setup.d.ts.map +1 -1
- package/build/commands/setup.js +7 -4
- package/build/commands/setup.js.map +1 -1
- package/build/commands/sync.js +12 -8
- package/build/commands/sync.js.map +1 -1
- package/build/commands/uninstall.d.ts.map +1 -1
- package/build/commands/uninstall.js +25 -11
- package/build/commands/uninstall.js.map +1 -1
- package/build/commands/update.d.ts.map +1 -1
- package/build/commands/update.js +19 -5
- package/build/commands/update.js.map +1 -1
- package/build/components/ExcludedSkippedHint.d.ts +13 -0
- package/build/components/ExcludedSkippedHint.d.ts.map +1 -0
- package/build/components/ExcludedSkippedHint.js +12 -0
- package/build/components/ExcludedSkippedHint.js.map +1 -0
- package/build/components/StatusBadge.d.ts +1 -1
- package/build/components/StatusBadge.d.ts.map +1 -1
- package/build/components/StatusBadge.js +2 -0
- package/build/components/StatusBadge.js.map +1 -1
- package/build/components/SyncAllInSync.d.ts +3 -1
- package/build/components/SyncAllInSync.d.ts.map +1 -1
- package/build/components/SyncAllInSync.js +3 -2
- package/build/components/SyncAllInSync.js.map +1 -1
- package/build/components/SyncDriftedList.d.ts +3 -1
- package/build/components/SyncDriftedList.d.ts.map +1 -1
- package/build/components/SyncDriftedList.js +4 -3
- package/build/components/SyncDriftedList.js.map +1 -1
- package/build/components/index.d.ts +1 -0
- package/build/components/index.d.ts.map +1 -1
- package/build/components/index.js +1 -0
- package/build/components/index.js.map +1 -1
- package/build/hooks/useListActions.d.ts +1 -0
- package/build/hooks/useListActions.d.ts.map +1 -1
- package/build/hooks/useListActions.js +1 -0
- package/build/hooks/useListActions.js.map +1 -1
- package/build/hooks/usePruneState.d.ts +1 -1
- package/build/hooks/usePruneState.d.ts.map +1 -1
- package/build/hooks/usePruneState.js +11 -5
- package/build/hooks/usePruneState.js.map +1 -1
- package/build/hooks/useSetupState.d.ts +2 -1
- package/build/hooks/useSetupState.d.ts.map +1 -1
- package/build/hooks/useSetupState.js +17 -6
- package/build/hooks/useSetupState.js.map +1 -1
- package/build/hooks/useUninstallState.d.ts +21 -9
- package/build/hooks/useUninstallState.d.ts.map +1 -1
- package/build/hooks/useUninstallState.js +61 -8
- package/build/hooks/useUninstallState.js.map +1 -1
- package/build/lib/asset-tools.d.ts +55 -0
- package/build/lib/asset-tools.d.ts.map +1 -0
- package/build/lib/asset-tools.js +71 -0
- package/build/lib/asset-tools.js.map +1 -0
- package/build/lib/config-entries.d.ts +52 -0
- package/build/lib/config-entries.d.ts.map +1 -0
- package/build/lib/config-entries.js +71 -0
- package/build/lib/config-entries.js.map +1 -0
- package/build/lib/diff-command.d.ts.map +1 -1
- package/build/lib/diff-command.js +8 -0
- package/build/lib/diff-command.js.map +1 -1
- package/build/lib/installer.d.ts.map +1 -1
- package/build/lib/installer.js +21 -3
- package/build/lib/installer.js.map +1 -1
- package/build/lib/schemas/lockfile.d.ts +5 -0
- package/build/lib/schemas/lockfile.d.ts.map +1 -1
- package/build/lib/schemas/lockfile.js +8 -0
- package/build/lib/schemas/lockfile.js.map +1 -1
- package/build/lib/setup.d.ts +6 -0
- package/build/lib/setup.d.ts.map +1 -1
- package/build/lib/setup.js +49 -4
- package/build/lib/setup.js.map +1 -1
- package/build/lib/sync.d.ts +9 -1
- package/build/lib/sync.d.ts.map +1 -1
- package/build/lib/sync.js +31 -8
- package/build/lib/sync.js.map +1 -1
- package/build/lib/uninstaller.d.ts +35 -0
- package/build/lib/uninstaller.d.ts.map +1 -1
- package/build/lib/uninstaller.js +84 -18
- package/build/lib/uninstaller.js.map +1 -1
- package/build/lib/updater.d.ts +6 -0
- package/build/lib/updater.d.ts.map +1 -1
- package/build/lib/updater.js +35 -3
- package/build/lib/updater.js.map +1 -1
- package/package.json +1 -1
package/build/lib/setup.d.ts
CHANGED
|
@@ -17,6 +17,12 @@ export interface SummaryAction {
|
|
|
17
17
|
detail?: string;
|
|
18
18
|
label: string;
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Parse the raw `atk setup --tool` values into a deduplicated, order-preserving list of tool
|
|
22
|
+
* ids. The flag is repeatable and each value may itself be comma-separated, so
|
|
23
|
+
* `--tool a --tool b`, `--tool a,b` and a mix of both all yield `['a', 'b']`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function parseToolsInput(values: string[]): string[];
|
|
20
26
|
/**
|
|
21
27
|
* Perform the setup creation step: write project config, write/update the
|
|
22
28
|
* lockfile, and ensure gitignore entries are present for the selected tools.
|
package/build/lib/setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/lib/setup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/lib/setup.ts"],"names":[],"mappings":"AAgBA;;;GAGG;AACH,eAAO,MAAM,WAAW,QAA4B,CAAC;AAMrD,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAMD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAa1D;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAoHtG"}
|
package/build/lib/setup.js
CHANGED
|
@@ -2,7 +2,7 @@ import { existsSync } from 'node:fs';
|
|
|
2
2
|
import { mkdir } from 'node:fs/promises';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { loadAdapter } from './adapter.js';
|
|
5
|
-
import { saveProjectConfig } from './config.js';
|
|
5
|
+
import { loadProjectConfig, saveProjectConfig } from './config.js';
|
|
6
6
|
import { ensureGitignoreEntries, ensureGitignorePatterns } from './gitignore.js';
|
|
7
7
|
import { getLockfilePath, readLockfile, writeLockfile } from './lockfile.js';
|
|
8
8
|
// ---------------------------------------------------------------------------
|
|
@@ -16,6 +16,23 @@ export const ORG_PATTERN = /^[a-zA-Z][a-zA-Z0-9-]*$/;
|
|
|
16
16
|
// ---------------------------------------------------------------------------
|
|
17
17
|
// Main function
|
|
18
18
|
// ---------------------------------------------------------------------------
|
|
19
|
+
/**
|
|
20
|
+
* Parse the raw `atk setup --tool` values into a deduplicated, order-preserving list of tool
|
|
21
|
+
* ids. The flag is repeatable and each value may itself be comma-separated, so
|
|
22
|
+
* `--tool a --tool b`, `--tool a,b` and a mix of both all yield `['a', 'b']`.
|
|
23
|
+
*/
|
|
24
|
+
export function parseToolsInput(values) {
|
|
25
|
+
const result = [];
|
|
26
|
+
for (const value of values) {
|
|
27
|
+
for (const part of value.split(',')) {
|
|
28
|
+
const trimmed = part.trim();
|
|
29
|
+
if (trimmed && !result.includes(trimmed)) {
|
|
30
|
+
result.push(trimmed);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
19
36
|
/**
|
|
20
37
|
* Perform the setup creation step: write project config, write/update the
|
|
21
38
|
* lockfile, and ensure gitignore entries are present for the selected tools.
|
|
@@ -32,9 +49,28 @@ export async function performSetupCreation(options) {
|
|
|
32
49
|
if (resolvedOrg !== undefined && !ORG_PATTERN.test(resolvedOrg)) {
|
|
33
50
|
throw new Error(`Invalid org "${resolvedOrg}": must start with a letter and contain only letters, digits, or hyphens.`);
|
|
34
51
|
}
|
|
35
|
-
// 1. Write .atkrc.json with { tools: [...] }
|
|
36
|
-
|
|
37
|
-
|
|
52
|
+
// 1. Write .atkrc.json with { tools: [...] }. Setup replaces the tools list, so say which
|
|
53
|
+
// list it replaced and which tools dropped out of it.
|
|
54
|
+
// Frozen assets are not setup's to change, so they carry over.
|
|
55
|
+
const previousConfig = await loadPreviousConfig(projectDir);
|
|
56
|
+
const previousTools = previousConfig?.tools ?? [];
|
|
57
|
+
await saveProjectConfig(projectDir, {
|
|
58
|
+
...(previousConfig?.frozenAssets?.length ? { frozenAssets: previousConfig.frozenAssets } : {}),
|
|
59
|
+
tools: selectedTools,
|
|
60
|
+
});
|
|
61
|
+
const listChanged = previousTools.length > 0 &&
|
|
62
|
+
(previousTools.length !== selectedTools.length || previousTools.some((t, i) => t !== selectedTools[i]));
|
|
63
|
+
actions.push({
|
|
64
|
+
detail: `tools: ${selectedTools.join(', ')}${listChanged ? ` — replaced: ${previousTools.join(', ')}` : ''}`,
|
|
65
|
+
label: 'Wrote .atkrc.json',
|
|
66
|
+
});
|
|
67
|
+
const removedTools = previousTools.filter((t) => !selectedTools.includes(t));
|
|
68
|
+
if (removedTools.length > 0) {
|
|
69
|
+
actions.push({
|
|
70
|
+
detail: `${removedTools.join(', ')} — installed files and config directories were left in place`,
|
|
71
|
+
label: 'Removed from tools list',
|
|
72
|
+
});
|
|
73
|
+
}
|
|
38
74
|
// 2. Write/update .atk-lock.json
|
|
39
75
|
const lockfilePath = getLockfilePath(projectDir);
|
|
40
76
|
if (existsSync(lockfilePath)) {
|
|
@@ -134,4 +170,13 @@ async function ensureToolMarkerDir(projectDir, adapter) {
|
|
|
134
170
|
await mkdir(join(projectDir, dirIndicator), { recursive: true });
|
|
135
171
|
return dirIndicator;
|
|
136
172
|
}
|
|
173
|
+
/** The existing `.atkrc.json`, or null when it is absent or unreadable. */
|
|
174
|
+
async function loadPreviousConfig(projectDir) {
|
|
175
|
+
try {
|
|
176
|
+
return await loadProjectConfig(projectDir);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
137
182
|
//# sourceMappingURL=setup.js.map
|
package/build/lib/setup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/lib/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/lib/setup.ts"],"names":[],"mappings":"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"}
|
package/build/lib/sync.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export interface ClassifySyncEntriesOptions {
|
|
|
12
12
|
projectDir: string;
|
|
13
13
|
}
|
|
14
14
|
export interface ClassifySyncEntriesResult {
|
|
15
|
+
/** Assets skipped because they were uninstalled for this tool (`excludedTools`). */
|
|
16
|
+
excludedSkipped: number;
|
|
15
17
|
frozenSkipped: number;
|
|
16
18
|
skipped: number;
|
|
17
19
|
toSync: SyncEntry[];
|
|
@@ -57,6 +59,8 @@ export type SyncOutcome = {
|
|
|
57
59
|
};
|
|
58
60
|
export interface ToolDryRunResult {
|
|
59
61
|
bootstrapHint?: string;
|
|
62
|
+
/** Assets skipped because they were uninstalled for this tool. Absent when zero. */
|
|
63
|
+
excludedSkipped?: number;
|
|
60
64
|
frozenSkipped: number;
|
|
61
65
|
skipped: number;
|
|
62
66
|
tool: string;
|
|
@@ -64,6 +68,8 @@ export interface ToolDryRunResult {
|
|
|
64
68
|
}
|
|
65
69
|
export interface ToolSyncResult {
|
|
66
70
|
bootstrapHint?: string;
|
|
71
|
+
/** Assets skipped because they were uninstalled for this tool. Absent when zero. */
|
|
72
|
+
excludedSkipped?: number;
|
|
67
73
|
failures: SyncFailure[];
|
|
68
74
|
frozenSkipped: number;
|
|
69
75
|
skipped: number;
|
|
@@ -76,7 +82,9 @@ export interface ToolSyncResult {
|
|
|
76
82
|
* that previously appeared in both the dry-run and live sync paths.
|
|
77
83
|
*
|
|
78
84
|
* For each asset the function:
|
|
79
|
-
* 1. Checks if the asset is frozen — if so, increments `frozenSkipped`.
|
|
85
|
+
* 1. Checks if the asset is frozen — if so, increments `frozenSkipped`. An asset that was
|
|
86
|
+
* uninstalled for this tool (`excludedTools`) increments `excludedSkipped` — even under
|
|
87
|
+
* `force`, so sync never resurrects it.
|
|
80
88
|
* 2. If `force` is true, marks it as `forced` without checking checksums.
|
|
81
89
|
* 3. Otherwise, resolves installed paths via the adapter, verifies both file
|
|
82
90
|
* checksums AND registered config-entry checksums (e.g. a hook's
|
package/build/lib/sync.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/lib/sync.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/lib/sync.ts"],"names":[],"mappings":"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"}
|
package/build/lib/sync.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
2
|
import { resolveInstalledPaths } from './adapter.js';
|
|
3
|
+
import { isExcludedForTool, supportsType } from './asset-tools.js';
|
|
3
4
|
import { verifyChecksums, verifyConfigEntries } from './checksum.js';
|
|
5
|
+
import { getConfigEntriesForTool, needsConfigRegistration } from './config-entries.js';
|
|
4
6
|
import { isFrozenInConfig } from './config.js';
|
|
5
7
|
import { executeInstallPlan, InstallerError } from './installer.js';
|
|
6
8
|
import { addAssetToLockfile, readLockfile, removeAssetFromLockfile, withLockfileErrorHandling, writeLockfile, } from './lockfile.js';
|
|
@@ -15,7 +17,9 @@ import { removeSingleAsset, UninstallerError } from './uninstaller.js';
|
|
|
15
17
|
* that previously appeared in both the dry-run and live sync paths.
|
|
16
18
|
*
|
|
17
19
|
* For each asset the function:
|
|
18
|
-
* 1. Checks if the asset is frozen — if so, increments `frozenSkipped`.
|
|
20
|
+
* 1. Checks if the asset is frozen — if so, increments `frozenSkipped`. An asset that was
|
|
21
|
+
* uninstalled for this tool (`excludedTools`) increments `excludedSkipped` — even under
|
|
22
|
+
* `force`, so sync never resurrects it.
|
|
19
23
|
* 2. If `force` is true, marks it as `forced` without checking checksums.
|
|
20
24
|
* 3. Otherwise, resolves installed paths via the adapter, verifies both file
|
|
21
25
|
* checksums AND registered config-entry checksums (e.g. a hook's
|
|
@@ -25,6 +29,7 @@ import { removeSingleAsset, UninstallerError } from './uninstaller.js';
|
|
|
25
29
|
export async function classifySyncEntries(options) {
|
|
26
30
|
const { adapter, assets, force, onProgress, projectConfig, projectDir } = options;
|
|
27
31
|
const toSync = [];
|
|
32
|
+
let excludedSkipped = 0;
|
|
28
33
|
let frozenSkipped = 0;
|
|
29
34
|
let skipped = 0;
|
|
30
35
|
for (const asset of assets) {
|
|
@@ -33,6 +38,17 @@ export async function classifySyncEntries(options) {
|
|
|
33
38
|
frozenSkipped++;
|
|
34
39
|
continue;
|
|
35
40
|
}
|
|
41
|
+
if (isExcludedForTool(asset, adapter.tool)) {
|
|
42
|
+
excludedSkipped++;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
// This tool has no placement for the asset type (e.g. Codex CLI and rules): there is
|
|
46
|
+
// nothing to sync. Checked before `force`, which would otherwise hand the asset to the
|
|
47
|
+
// installer and report a spurious "does not support asset type" failure.
|
|
48
|
+
if (!supportsType(adapter, asset.type)) {
|
|
49
|
+
skipped++;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
36
52
|
if (force) {
|
|
37
53
|
toSync.push({ asset, reason: 'forced' });
|
|
38
54
|
continue;
|
|
@@ -45,22 +61,26 @@ export async function classifySyncEntries(options) {
|
|
|
45
61
|
const checksumFailures = await verifyChecksums(filesToCheck);
|
|
46
62
|
// Also verify registered config entries (e.g. a hook's `hooks.<Event>` group or an
|
|
47
63
|
// mcp server block). Config-only drift leaves the asset's files intact, so it is
|
|
48
|
-
// invisible to file checksums alone — check both before deciding to skip.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
64
|
+
// invisible to file checksums alone — check both before deciding to skip. The lockfile
|
|
65
|
+
// is shared across tools, so only this tool's entries are verified.
|
|
66
|
+
const ownConfigEntries = getConfigEntriesForTool(asset, adapter);
|
|
67
|
+
const configFailures = ownConfigEntries.length ? await verifyConfigEntries(ownConfigEntries, projectDir) : [];
|
|
68
|
+
// Another tool recorded config entries for this asset but this tool never did (e.g. it
|
|
69
|
+
// was installed or last synced under a different tool) — reinstall to register it here.
|
|
70
|
+
const needsRegistration = needsConfigRegistration(asset, adapter);
|
|
71
|
+
if (checksumFailures.length === 0 && configFailures.length === 0 && !needsRegistration) {
|
|
53
72
|
skipped++;
|
|
54
73
|
continue;
|
|
55
74
|
}
|
|
56
|
-
const hasMissing =
|
|
75
|
+
const hasMissing = needsRegistration ||
|
|
76
|
+
checksumFailures.some((f) => f.actual.startsWith('FILE_NOT_FOUND')) ||
|
|
57
77
|
configFailures.some((f) => f.reason === 'CONFIG_FILE_NOT_FOUND' || f.reason === 'CONFIG_KEY_NOT_FOUND');
|
|
58
78
|
toSync.push({
|
|
59
79
|
asset,
|
|
60
80
|
reason: hasMissing ? 'missing' : 'modified',
|
|
61
81
|
});
|
|
62
82
|
}
|
|
63
|
-
return { frozenSkipped, skipped, toSync };
|
|
83
|
+
return { excludedSkipped, frozenSkipped, skipped, toSync };
|
|
64
84
|
}
|
|
65
85
|
/**
|
|
66
86
|
* Perform a dry-run sync: read the lockfile (without locking), classify each
|
|
@@ -96,6 +116,7 @@ export async function dryRunSync(options) {
|
|
|
96
116
|
projectDir,
|
|
97
117
|
});
|
|
98
118
|
toolResults.push({
|
|
119
|
+
...(classified.excludedSkipped > 0 ? { excludedSkipped: classified.excludedSkipped } : {}),
|
|
99
120
|
frozenSkipped: classified.frozenSkipped,
|
|
100
121
|
skipped: classified.skipped,
|
|
101
122
|
tool: toolName,
|
|
@@ -149,6 +170,7 @@ export async function syncAssets(options) {
|
|
|
149
170
|
});
|
|
150
171
|
if (classified.toSync.length === 0) {
|
|
151
172
|
toolResults.push({
|
|
173
|
+
...(classified.excludedSkipped > 0 ? { excludedSkipped: classified.excludedSkipped } : {}),
|
|
152
174
|
failures: [],
|
|
153
175
|
frozenSkipped: classified.frozenSkipped,
|
|
154
176
|
skipped: classified.skipped,
|
|
@@ -209,6 +231,7 @@ export async function syncAssets(options) {
|
|
|
209
231
|
}
|
|
210
232
|
}
|
|
211
233
|
toolResults.push({
|
|
234
|
+
...(classified.excludedSkipped > 0 ? { excludedSkipped: classified.excludedSkipped } : {}),
|
|
212
235
|
failures,
|
|
213
236
|
frozenSkipped: classified.frozenSkipped,
|
|
214
237
|
skipped: classified.skipped,
|
package/build/lib/sync.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/lib/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAQjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,uBAAuB,EACvB,yBAAyB,EACzB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/lib/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAQjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,uBAAuB,EACvB,yBAAyB,EACzB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAwFvE,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAmC;IAC3E,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAElF,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,UAAU,EAAE,CAAC,YAAY,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC;QAE1C,IAAI,gBAAgB,CAAC,aAAa,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACvE,aAAa,EAAE,CAAC;YAChB,SAAS;QACX,CAAC;QAED,IAAI,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,eAAe,EAAE,CAAC;YAClB,SAAS;QACX,CAAC;QAED,qFAAqF;QACrF,uFAAuF;QACvF,yEAAyE;QACzE,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,OAAO,EAAE,CAAC;YACV,SAAS;QACX,CAAC;QAED,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;YACzC,SAAS;QACX,CAAC;QAED,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QACnE,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC9C,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,aAAa,CAAC;SACxC,CAAC,CAAC,CAAC;QAEJ,MAAM,gBAAgB,GAAG,MAAM,eAAe,CAAC,YAAY,CAAC,CAAC;QAE7D,mFAAmF;QACnF,iFAAiF;QACjF,uFAAuF;QACvF,oEAAoE;QACpE,MAAM,gBAAgB,GAAG,uBAAuB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACjE,MAAM,cAAc,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,mBAAmB,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAE9G,uFAAuF;QACvF,wFAAwF;QACxF,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAElE,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvF,OAAO,EAAE,CAAC;YACV,SAAS;QACX,CAAC;QAED,MAAM,UAAU,GACd,iBAAiB;YACjB,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;YACnE,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,uBAAuB,IAAI,CAAC,CAAC,MAAM,KAAK,sBAAsB,CAAC,CAAC;QAC1G,MAAM,CAAC,IAAI,CAAC;YACV,KAAK;YACL,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU;SAC5C,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC7D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAA0B;IACzD,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAExE,UAAU,EAAE,CAAC,qBAAqB,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;IAEhD,MAAM,WAAW,GAAuB,EAAE,CAAC;IAE3C,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,KAAK,EAAE,CAAC;QAChD,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC;QAEzC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,WAAW,CAAC,IAAI,CAAC;gBACf,aAAa,EAAE,mDAAmD,QAAQ,EAAE;gBAC5E,aAAa,EAAE,CAAC;gBAChB,OAAO,EAAE,CAAC;gBACV,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,EAAE;aACX,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC;YAC3C,OAAO;YACP,MAAM,EAAE,UAAU;YAClB,KAAK;YACL,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,GAAG,QAAQ,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;YAC1F,aAAa;YACb,UAAU;SACX,CAAC,CAAC;QAEH,WAAW,CAAC,IAAI,CAAC;YACf,GAAG,CAAC,UAAU,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,UAAU,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1F,aAAa,EAAE,UAAU,CAAC,aAAa;YACvC,OAAO,EAAE,UAAU,CAAC,OAAO;YAC3B,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,8EAA8E;AAC9E,0BAA0B;AAC1B,8EAA8E;AAE9E;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAA0B;IACzD,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAElF,OAAO,yBAAyB,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;QACtD,UAAU,EAAE,CAAC,qBAAqB,CAAC,CAAC;QACpC,IAAI,QAAQ,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;QAE9C,MAAM,WAAW,GAAqB,EAAE,CAAC;QAEzC,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,KAAK,EAAE,CAAC;YAChD,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC;YAEzC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC5B,WAAW,CAAC,IAAI,CAAC;oBACf,aAAa,EAAE,qDAAqD;oBACpE,QAAQ,EAAE,EAAE;oBACZ,aAAa,EAAE,CAAC;oBAChB,OAAO,EAAE,CAAC;oBACV,MAAM,EAAE,EAAE;oBACV,IAAI,EAAE,QAAQ;iBACf,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YAED,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC;gBAC3C,OAAO;gBACP,MAAM,EAAE,UAAU;gBAClB,KAAK;gBACL,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,GAAG,QAAQ,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;gBAC1F,aAAa;gBACb,UAAU;aACX,CAAC,CAAC;YAEH,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACnC,WAAW,CAAC,IAAI,CAAC;oBACf,GAAG,CAAC,UAAU,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,UAAU,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC1F,QAAQ,EAAE,EAAE;oBACZ,aAAa,EAAE,UAAU,CAAC,aAAa;oBACvC,OAAO,EAAE,UAAU,CAAC,OAAO;oBAC3B,MAAM,EAAE,EAAE;oBACV,IAAI,EAAE,QAAQ;iBACf,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YAED,MAAM,QAAQ,GAAkB,EAAE,CAAC;YAEnC,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;gBACtC,UAAU,EAAE,CAAC,WAAW,KAAK,CAAC,KAAK,CAAC,IAAI,QAAQ,QAAQ,KAAK,CAAC,CAAC;gBAE/D,6EAA6E;gBAC7E,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC;gBAElC,qEAAqE;gBACrE,wEAAwE;gBACxE,qBAAqB;gBACrB,IAAI,CAAC;oBACH,MAAM,iBAAiB,CAAC,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;gBAC1E,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,CAAC,KAAK,YAAY,gBAAgB,CAAC,EAAE,CAAC;wBACzC,MAAM,KAAK,CAAC;oBACd,CAAC;gBACH,CAAC;gBAED,kDAAkD;gBAClD,QAAQ,GAAG,uBAAuB,CAAC,QAAQ,EAAE,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;gBAExG,qFAAqF;gBACrF,mEAAmE;gBACnE,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,kBAAkB,CAC7B,QAAQ,EACR,aAAa,CAAC,IAAI,EAClB,aAAa,CAAC,IAAI,EAClB,aAAa,CAAC,OAAO,EACrB,aAAa,CAAC,GAAG,CAClB,CAAC;oBACF,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI,CAAC,CAAC;oBACtF,MAAM,UAAU,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC;oBAEhF,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,UAAU,EAAE;wBACnD,OAAO;wBACP,UAAU;wBACV,UAAU;qBACX,CAAC,CAAC;oBAEH,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;oBAE1B,qEAAqE;oBACrE,mEAAmE;oBACnE,0BAA0B;oBAC1B,QAAQ,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;gBAC5C,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,KAAK,YAAY,aAAa,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;wBACtE,kEAAkE;wBAClE,kEAAkE;wBAClE,QAAQ,GAAG,kBAAkB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;wBAEvD,QAAQ,CAAC,IAAI,CAAC;4BACZ,SAAS,EAAE,aAAa,CAAC,IAAI;4BAC7B,SAAS,EAAE,aAAa,CAAC,IAAI;4BAC7B,KAAK,EAAE,KAAK,CAAC,OAAO;4BACpB,OAAO,EAAE,aAAa,CAAC,OAAO;yBAC/B,CAAC,CAAC;wBACH,SAAS;oBACX,CAAC;oBAED,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;YAED,WAAW,CAAC,IAAI,CAAC;gBACf,GAAG,CAAC,UAAU,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,UAAU,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1F,QAAQ;gBACR,aAAa,EAAE,UAAU,CAAC,aAAa;gBACvC,OAAO,EAAE,UAAU,CAAC,OAAO;gBAC3B,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC;gBAC/D,IAAI,EAAE,QAAQ;aACf,CAAC,CAAC;QACL,CAAC;QAED,wEAAwE;QACxE,kDAAkD;QAClD,MAAM,aAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAE1C,OAAO,WAAW,CAAC;IACrB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -20,6 +20,15 @@ export interface BundleUninstallResult {
|
|
|
20
20
|
asset: string;
|
|
21
21
|
error: string;
|
|
22
22
|
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Assets whose lockfile entry was kept because other tools still have them (tool-scoped
|
|
25
|
+
* uninstall only). Absent when every entry was dropped.
|
|
26
|
+
*/
|
|
27
|
+
keptEntries?: Array<{
|
|
28
|
+
name: string;
|
|
29
|
+
remainingTools: string[];
|
|
30
|
+
type: string;
|
|
31
|
+
}>;
|
|
23
32
|
removedAssets: Array<{
|
|
24
33
|
name: string;
|
|
25
34
|
type: string;
|
|
@@ -40,8 +49,20 @@ export interface BundleUninstallResult {
|
|
|
40
49
|
export interface UninstallOptions {
|
|
41
50
|
/** Tool adapter for resolving file paths and config entries. */
|
|
42
51
|
adapter: Adapter;
|
|
52
|
+
/**
|
|
53
|
+
* Other configured tools' adapters. Each removed asset is also cleaned from disk for these
|
|
54
|
+
* tools, so callers that drop the lockfile entry in a single pass (bundle uninstall, prune)
|
|
55
|
+
* do not strand the other tools' files and config registrations.
|
|
56
|
+
*/
|
|
57
|
+
additionalAdapters?: Adapter[];
|
|
43
58
|
/** Whether to cascade-remove orphaned dependencies. Default: true. */
|
|
44
59
|
cascade?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Keep the primary asset's lockfile entry after removing it from disk. Used by update,
|
|
62
|
+
* which reinstalls straight away: the surviving entry lets the installer carry over the
|
|
63
|
+
* config entries other tools registered for the asset.
|
|
64
|
+
*/
|
|
65
|
+
keepLockfileEntry?: boolean;
|
|
45
66
|
/** Pre-computed lockfile to avoid re-reading from disk. */
|
|
46
67
|
lockfile?: Lockfile;
|
|
47
68
|
/** Callback for progress updates. */
|
|
@@ -52,6 +73,16 @@ export interface UninstallOptions {
|
|
|
52
73
|
plan?: UninstallPlan;
|
|
53
74
|
/** Project root directory. */
|
|
54
75
|
projectDir: string;
|
|
76
|
+
/**
|
|
77
|
+
* Set for a tool-scoped uninstall (`--tool`): the removal only covers the given adapters, so
|
|
78
|
+
* an asset that other tools still have keeps its lockfile entry — the removed tools are
|
|
79
|
+
* recorded in its `excludedTools` and only their config entries are dropped. The entry is
|
|
80
|
+
* removed only when no tool still has the asset. `configuredAdapters` are the adapters of
|
|
81
|
+
* every tool configured for the project. Omit to always drop the entry.
|
|
82
|
+
*/
|
|
83
|
+
toolScope?: {
|
|
84
|
+
configuredAdapters: Adapter[];
|
|
85
|
+
};
|
|
55
86
|
}
|
|
56
87
|
export interface UninstallPlan {
|
|
57
88
|
/** Other installed assets that depend on the asset being removed. */
|
|
@@ -67,9 +98,13 @@ export interface UninstallResult {
|
|
|
67
98
|
key: string;
|
|
68
99
|
}>;
|
|
69
100
|
filesRemoved: string[];
|
|
101
|
+
/** True when the lockfile entry was kept because other tools still have the asset. */
|
|
102
|
+
lockfileEntryKept?: boolean;
|
|
70
103
|
name: string;
|
|
71
104
|
/** Whether this was the primary uninstall target or a cascade-removed orphan. */
|
|
72
105
|
reason: 'direct' | 'orphan';
|
|
106
|
+
/** Tools that still have the asset (set when `lockfileEntryKept` is true). */
|
|
107
|
+
remainingTools?: string[];
|
|
73
108
|
type: string;
|
|
74
109
|
version: string;
|
|
75
110
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uninstaller.d.ts","sourceRoot":"","sources":["../../src/lib/uninstaller.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"uninstaller.d.ts","sourceRoot":"","sources":["../../src/lib/uninstaller.ts"],"names":[],"mappings":"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"}
|
package/build/lib/uninstaller.js
CHANGED
|
@@ -2,6 +2,8 @@ import { existsSync } from 'node:fs';
|
|
|
2
2
|
import { readdir, readFile, rmdir, unlink } from 'node:fs/promises';
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
4
|
import { getPlacement, resolveInstalledPaths } from './adapter.js';
|
|
5
|
+
import { excludeToolFromAsset, getRemainingTools, supportsType } from './asset-tools.js';
|
|
6
|
+
import { getConfigEntriesForTool } from './config-entries.js';
|
|
5
7
|
import { detectConfigFormat, readConfigFile, resolveConfigFormat, writeConfigFile, } from './config-file.js';
|
|
6
8
|
import {} from './errors.js';
|
|
7
9
|
import { removeHookGroup } from './hook-config.js';
|
|
@@ -25,9 +27,11 @@ export async function executeBundleUninstall(plan, options) {
|
|
|
25
27
|
// Bundle membership was already resolved by planBundleUninstall keyed on
|
|
26
28
|
// bundleOrigin (name, org); each removal below uses the asset's own org, so
|
|
27
29
|
// no ambient org scope participates here.
|
|
28
|
-
const { adapter, onProgress, projectDir } = options;
|
|
30
|
+
const { adapter, additionalAdapters = [], onProgress, projectDir, toolScope } = options;
|
|
31
|
+
const adapters = [adapter, ...additionalAdapters];
|
|
29
32
|
return withLockfileLock(projectDir, async () => {
|
|
30
33
|
let lockfile = await readLockfile(projectDir);
|
|
34
|
+
const keptEntries = [];
|
|
31
35
|
const removedAssets = [];
|
|
32
36
|
const removedOrphans = [];
|
|
33
37
|
const skippedAssets = plan.assetsToSkip.map((a) => ({
|
|
@@ -41,8 +45,12 @@ export async function executeBundleUninstall(plan, options) {
|
|
|
41
45
|
for (const asset of plan.assetsToRemove) {
|
|
42
46
|
try {
|
|
43
47
|
onProgress?.(`Removing ${asset.name}...`);
|
|
44
|
-
await
|
|
45
|
-
|
|
48
|
+
await removeAssetForAdapters(asset, adapters, projectDir, onProgress);
|
|
49
|
+
const dropped = dropOrExcludeEntry(lockfile, asset, adapters, toolScope);
|
|
50
|
+
lockfile = dropped.lockfile;
|
|
51
|
+
if (dropped.remainingTools.length > 0) {
|
|
52
|
+
keptEntries.push({ name: asset.name, remainingTools: dropped.remainingTools, type: asset.type });
|
|
53
|
+
}
|
|
46
54
|
removedAssets.push({ name: asset.name, type: asset.type, version: asset.version });
|
|
47
55
|
}
|
|
48
56
|
catch (err) {
|
|
@@ -56,8 +64,12 @@ export async function executeBundleUninstall(plan, options) {
|
|
|
56
64
|
for (const orphan of plan.orphansToRemove) {
|
|
57
65
|
try {
|
|
58
66
|
onProgress?.(`Removing orphaned dependency ${orphan.name}...`);
|
|
59
|
-
await
|
|
60
|
-
|
|
67
|
+
await removeAssetForAdapters(orphan, adapters, projectDir, onProgress);
|
|
68
|
+
const dropped = dropOrExcludeEntry(lockfile, orphan, adapters, toolScope);
|
|
69
|
+
lockfile = dropped.lockfile;
|
|
70
|
+
if (dropped.remainingTools.length > 0) {
|
|
71
|
+
keptEntries.push({ name: orphan.name, remainingTools: dropped.remainingTools, type: orphan.type });
|
|
72
|
+
}
|
|
61
73
|
removedOrphans.push({ name: orphan.name, type: orphan.type, version: orphan.version });
|
|
62
74
|
}
|
|
63
75
|
catch (err) {
|
|
@@ -70,7 +82,13 @@ export async function executeBundleUninstall(plan, options) {
|
|
|
70
82
|
// Write lockfile once at the end
|
|
71
83
|
onProgress?.(`Updating lockfile...`);
|
|
72
84
|
await writeLockfile(projectDir, lockfile);
|
|
73
|
-
return {
|
|
85
|
+
return {
|
|
86
|
+
errors,
|
|
87
|
+
...(keptEntries.length > 0 ? { keptEntries } : {}),
|
|
88
|
+
removedAssets,
|
|
89
|
+
removedOrphans,
|
|
90
|
+
skippedAssets,
|
|
91
|
+
};
|
|
74
92
|
});
|
|
75
93
|
}
|
|
76
94
|
/**
|
|
@@ -196,10 +214,13 @@ export async function removeSingleAsset(installed, adapter, projectDir, onProgre
|
|
|
196
214
|
}
|
|
197
215
|
}
|
|
198
216
|
// Clean up config entries. Prefer the asset's stored lockfile entries — they hold the real
|
|
199
|
-
// registered keys (e.g. mcpServers.<serverName>, which may differ from the asset name) —
|
|
200
|
-
//
|
|
201
|
-
|
|
202
|
-
|
|
217
|
+
// registered keys (e.g. mcpServers.<serverName>, which may differ from the asset name) — but
|
|
218
|
+
// only the ones this adapter's tool registered: the lockfile is shared across tools, and
|
|
219
|
+
// removing for one tool must never touch another tool's config file. Fall back to the
|
|
220
|
+
// adapter-reconstructed entries when this tool has none recorded (older lockfiles).
|
|
221
|
+
const ownEntries = getConfigEntriesForTool(installed, adapter);
|
|
222
|
+
const entriesToClean = ownEntries.length > 0
|
|
223
|
+
? ownEntries.map((e) => ({ command: e.command, file: e.file, key: e.key }))
|
|
203
224
|
: resolved.configEntries;
|
|
204
225
|
const placement = getPlacement(adapter, installed.type);
|
|
205
226
|
const configEntriesCleaned = [];
|
|
@@ -222,9 +243,7 @@ export async function removeSingleAsset(installed, adapter, projectDir, onProgre
|
|
|
222
243
|
// Reverse any enabled-list registrations (e.g. enabledMcpjsonServers in settings.local.json).
|
|
223
244
|
if (placement?.enabledListFile && placement.enabledListKey && placement.configKey) {
|
|
224
245
|
const prefix = `${placement.configKey}.`;
|
|
225
|
-
const names = entriesToClean
|
|
226
|
-
.filter((e) => e.key.startsWith(prefix))
|
|
227
|
-
.map((e) => e.key.slice(prefix.length));
|
|
246
|
+
const names = entriesToClean.filter((e) => e.key.startsWith(prefix)).map((e) => e.key.slice(prefix.length));
|
|
228
247
|
if (names.length > 0) {
|
|
229
248
|
await removeFromEnabledList(join(projectDir, placement.enabledListFile), placement.enabledListKey, names, onProgress);
|
|
230
249
|
}
|
|
@@ -235,18 +254,25 @@ export async function removeSingleAsset(installed, adapter, projectDir, onProgre
|
|
|
235
254
|
* Uninstall a single asset by name, with optional cascade removal of orphaned dependencies.
|
|
236
255
|
*/
|
|
237
256
|
export async function uninstallAsset(assetName, options) {
|
|
238
|
-
const { adapter, cascade = true, lockfile: precomputedLockfile, onProgress, org, plan: precomputedPlan, projectDir, } = options;
|
|
257
|
+
const { adapter, additionalAdapters = [], cascade = true, keepLockfileEntry = false, lockfile: precomputedLockfile, onProgress, org, plan: precomputedPlan, projectDir, toolScope, } = options;
|
|
258
|
+
const adapters = [adapter, ...additionalAdapters];
|
|
239
259
|
onProgress?.(`Reading lockfile...`);
|
|
240
260
|
let lockfile = precomputedLockfile ?? (await readLockfile(projectDir));
|
|
241
261
|
// Compute the plan before removing anything
|
|
242
262
|
const plan = precomputedPlan ?? planUninstall(lockfile, assetName, org);
|
|
243
263
|
// Remove primary asset. Key the lockfile removal on the entry the plan resolved,
|
|
244
264
|
// not the caller-supplied org — the lookup may have fallen back to a global entry.
|
|
245
|
-
const primaryRemoval = await
|
|
246
|
-
|
|
265
|
+
const primaryRemoval = await removeAssetForAdapters(plan.primary, adapters, projectDir, onProgress);
|
|
266
|
+
let primaryRemainingTools = [];
|
|
267
|
+
if (!keepLockfileEntry) {
|
|
268
|
+
const dropped = dropOrExcludeEntry(lockfile, plan.primary, adapters, toolScope);
|
|
269
|
+
lockfile = dropped.lockfile;
|
|
270
|
+
primaryRemainingTools = dropped.remainingTools;
|
|
271
|
+
}
|
|
247
272
|
const results = [
|
|
248
273
|
{
|
|
249
274
|
...primaryRemoval,
|
|
275
|
+
...keptEntryFields(primaryRemainingTools),
|
|
250
276
|
name: plan.primary.name,
|
|
251
277
|
reason: 'direct',
|
|
252
278
|
type: plan.primary.type,
|
|
@@ -257,10 +283,12 @@ export async function uninstallAsset(assetName, options) {
|
|
|
257
283
|
if (cascade && plan.orphanedDependencies.length > 0) {
|
|
258
284
|
for (const orphan of plan.orphanedDependencies) {
|
|
259
285
|
onProgress?.(`Removing orphaned dependency ${orphan.name}...`);
|
|
260
|
-
const orphanRemoval = await
|
|
261
|
-
|
|
286
|
+
const orphanRemoval = await removeAssetForAdapters(orphan, adapters, projectDir, onProgress);
|
|
287
|
+
const dropped = dropOrExcludeEntry(lockfile, orphan, adapters, toolScope);
|
|
288
|
+
lockfile = dropped.lockfile;
|
|
262
289
|
results.push({
|
|
263
290
|
...orphanRemoval,
|
|
291
|
+
...keptEntryFields(dropped.remainingTools),
|
|
264
292
|
name: orphan.name,
|
|
265
293
|
reason: 'orphan',
|
|
266
294
|
type: orphan.type,
|
|
@@ -301,6 +329,44 @@ async function cleanupEmptyDirectories(dirPath, onProgress) {
|
|
|
301
329
|
onProgress?.(`Warning: Failed to clean up directory ${dirPath} — ${error instanceof Error ? error.message : String(error)}`);
|
|
302
330
|
}
|
|
303
331
|
}
|
|
332
|
+
/**
|
|
333
|
+
* Update the in-memory lockfile after an asset was removed from disk for `adapters`.
|
|
334
|
+
* A tool-scoped removal keeps the entry while other tools still have the asset (recording the
|
|
335
|
+
* removed tools in `excludedTools`); otherwise the entry is dropped.
|
|
336
|
+
*/
|
|
337
|
+
function dropOrExcludeEntry(lockfile, asset, adapters, toolScope) {
|
|
338
|
+
const remainingTools = toolScope
|
|
339
|
+
? getRemainingTools(asset, adapters.map((a) => a.tool), toolScope.configuredAdapters)
|
|
340
|
+
: [];
|
|
341
|
+
if (remainingTools.length === 0) {
|
|
342
|
+
return { lockfile: removeAssetFromLockfile(lockfile, asset.name, asset.type, asset.org), remainingTools };
|
|
343
|
+
}
|
|
344
|
+
// Replace the entry in place so a kept entry does not move within the committed lockfile.
|
|
345
|
+
// A tool that cannot place this asset type never had it, so it is not worth recording.
|
|
346
|
+
const kept = adapters
|
|
347
|
+
.filter((a) => supportsType(a, asset.type))
|
|
348
|
+
.reduce((entry, a) => excludeToolFromAsset(entry, a), asset);
|
|
349
|
+
const assets = (lockfile.assets ?? []).map((a) => a.name === asset.name && a.type === asset.type && a.org === asset.org ? kept : a);
|
|
350
|
+
return { lockfile: { ...lockfile, assets }, remainingTools };
|
|
351
|
+
}
|
|
352
|
+
/** Result fields describing a lockfile entry that survived a tool-scoped uninstall. */
|
|
353
|
+
function keptEntryFields(remainingTools) {
|
|
354
|
+
return remainingTools.length > 0 ? { lockfileEntryKept: true, remainingTools } : {};
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Remove a single asset from disk for every given adapter, merging the per-tool results.
|
|
358
|
+
* Each adapter only cleans the files and config entries of its own tool.
|
|
359
|
+
*/
|
|
360
|
+
async function removeAssetForAdapters(installed, adapters, projectDir, onProgress) {
|
|
361
|
+
const configEntriesCleaned = [];
|
|
362
|
+
const filesRemoved = [];
|
|
363
|
+
for (const adapter of adapters) {
|
|
364
|
+
const removal = await removeSingleAsset(installed, adapter, projectDir, onProgress);
|
|
365
|
+
configEntriesCleaned.push(...removal.configEntriesCleaned);
|
|
366
|
+
filesRemoved.push(...removal.filesRemoved);
|
|
367
|
+
}
|
|
368
|
+
return { configEntriesCleaned, filesRemoved };
|
|
369
|
+
}
|
|
304
370
|
/**
|
|
305
371
|
* Remove an asset's entry from a config file (e.g., settings.json).
|
|
306
372
|
* Reads the JSON config, removes the key associated with the asset, and writes back.
|