opkg 0.7.2 ā 0.7.4
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/commands/add.js +52 -26
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/apply.js +43 -4
- package/dist/commands/apply.js.map +1 -1
- package/dist/commands/install.js +132 -187
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/remove.js +18 -6
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/status.js +76 -22
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/uninstall.js +16 -4
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/core/add/add-conflict-handler.js +1 -3
- package/dist/core/add/add-conflict-handler.js.map +1 -1
- package/dist/core/add/add-context.js +9 -0
- package/dist/core/add/add-context.js.map +1 -0
- package/dist/core/add/add-to-source-pipeline.js +127 -65
- package/dist/core/add/add-to-source-pipeline.js.map +1 -1
- package/dist/core/add/platform-path-transformer.js +3 -2
- package/dist/core/add/platform-path-transformer.js.map +1 -1
- package/dist/core/add/source-collector.js +32 -13
- package/dist/core/add/source-collector.js.map +1 -1
- package/dist/core/apply/apply-pipeline.js +2 -2
- package/dist/core/apply/apply-pipeline.js.map +1 -1
- package/dist/core/conversion-context/creation.js +153 -0
- package/dist/core/conversion-context/creation.js.map +1 -0
- package/dist/core/conversion-context/index.js +13 -0
- package/dist/core/conversion-context/index.js.map +1 -0
- package/dist/core/conversion-context/serialization.js +129 -0
- package/dist/core/conversion-context/serialization.js.map +1 -0
- package/dist/core/conversion-context/validation.js +200 -0
- package/dist/core/conversion-context/validation.js.map +1 -0
- package/dist/core/dependency-resolver.js +1 -1
- package/dist/core/dependency-resolver.js.map +1 -1
- package/dist/core/discovery/file-discovery.js +18 -19
- package/dist/core/discovery/file-discovery.js.map +1 -1
- package/dist/core/discovery/platform-files-discovery.js +3 -2
- package/dist/core/discovery/platform-files-discovery.js.map +1 -1
- package/dist/core/flows/flow-execution-coordinator.js +268 -0
- package/dist/core/flows/flow-execution-coordinator.js.map +1 -0
- package/dist/core/flows/flow-executor.js +47 -34
- package/dist/core/flows/flow-executor.js.map +1 -1
- package/dist/core/flows/flow-source-discovery.js +287 -0
- package/dist/core/flows/flow-source-discovery.js.map +1 -0
- package/dist/core/flows/flow-transforms.js +2 -0
- package/dist/core/flows/flow-transforms.js.map +1 -1
- package/dist/core/flows/map-pipeline/operations/transform.js +45 -17
- package/dist/core/flows/map-pipeline/operations/transform.js.map +1 -1
- package/dist/core/flows/platform-converter.js +81 -46
- package/dist/core/flows/platform-converter.js.map +1 -1
- package/dist/core/flows/platform-suffix-handler.js +212 -0
- package/dist/core/flows/platform-suffix-handler.js.map +1 -0
- package/dist/core/install/dry-run.js +2 -11
- package/dist/core/install/dry-run.js.map +1 -1
- package/dist/core/install/flow-based/index.js +39 -0
- package/dist/core/install/flow-based/index.js.map +1 -0
- package/dist/core/install/flow-based/installer.js +207 -0
- package/dist/core/install/flow-based/installer.js.map +1 -0
- package/dist/core/install/flow-based/orchestration/conflict-tracker.js +103 -0
- package/dist/core/install/flow-based/orchestration/conflict-tracker.js.map +1 -0
- package/dist/core/install/flow-based/orchestration/index.js +9 -0
- package/dist/core/install/flow-based/orchestration/index.js.map +1 -0
- package/dist/core/install/flow-based/orchestration/multi-package.js +110 -0
- package/dist/core/install/flow-based/orchestration/multi-package.js.map +1 -0
- package/dist/core/install/flow-based/orchestration/result-aggregator.js +120 -0
- package/dist/core/install/flow-based/orchestration/result-aggregator.js.map +1 -0
- package/dist/core/install/flow-based/shared/filtering.js +86 -0
- package/dist/core/install/flow-based/shared/filtering.js.map +1 -0
- package/dist/core/install/flow-based/shared/flow-helpers.js +92 -0
- package/dist/core/install/flow-based/shared/flow-helpers.js.map +1 -0
- package/dist/core/install/flow-based/shared/index.js +9 -0
- package/dist/core/install/flow-based/shared/index.js.map +1 -0
- package/dist/core/install/flow-based/shared/result-converter.js +97 -0
- package/dist/core/install/flow-based/shared/result-converter.js.map +1 -0
- package/dist/core/install/flow-based/strategies/base.js +98 -0
- package/dist/core/install/flow-based/strategies/base.js.map +1 -0
- package/dist/core/install/flow-based/strategies/conversion.js +172 -0
- package/dist/core/install/flow-based/strategies/conversion.js.map +1 -0
- package/dist/core/install/flow-based/strategies/direct.js +82 -0
- package/dist/core/install/flow-based/strategies/direct.js.map +1 -0
- package/dist/core/install/flow-based/strategies/factory.js +158 -0
- package/dist/core/install/flow-based/strategies/factory.js.map +1 -0
- package/dist/core/install/flow-based/strategies/flow-based.js +75 -0
- package/dist/core/install/flow-based/strategies/flow-based.js.map +1 -0
- package/dist/core/install/flow-based/strategies/index.js +14 -0
- package/dist/core/install/flow-based/strategies/index.js.map +1 -0
- package/dist/core/install/flow-based/strategies/path-mapping.js +84 -0
- package/dist/core/install/flow-based/strategies/path-mapping.js.map +1 -0
- package/dist/core/install/flow-based-installer.js +65 -1132
- package/dist/core/install/flow-based-installer.js.map +1 -1
- package/dist/core/install/flow-installation-strategies.js +11 -0
- package/dist/core/install/flow-installation-strategies.js.map +1 -0
- package/dist/core/install/format-detector.js +29 -20
- package/dist/core/install/format-detector.js.map +1 -1
- package/dist/core/install/helpers/conflict-detection.js +71 -0
- package/dist/core/install/helpers/conflict-detection.js.map +1 -0
- package/dist/core/install/helpers/file-discovery.js +39 -0
- package/dist/core/install/helpers/file-discovery.js.map +1 -0
- package/dist/core/install/helpers/format-detection.js +66 -0
- package/dist/core/install/helpers/format-detection.js.map +1 -0
- package/dist/core/install/helpers/index.js +14 -0
- package/dist/core/install/helpers/index.js.map +1 -0
- package/dist/core/install/helpers/result-aggregation.js +107 -0
- package/dist/core/install/helpers/result-aggregation.js.map +1 -0
- package/dist/core/install/helpers/result-logging.js +85 -0
- package/dist/core/install/helpers/result-logging.js.map +1 -0
- package/dist/core/install/install-flow.js +5 -5
- package/dist/core/install/install-flow.js.map +1 -1
- package/dist/core/install/local-source-resolution.js.map +1 -1
- package/dist/core/install/marketplace-handler.js +186 -107
- package/dist/core/install/marketplace-handler.js.map +1 -1
- package/dist/core/install/operations/conflict-handler.js +103 -0
- package/dist/core/install/operations/conflict-handler.js.map +1 -0
- package/dist/core/install/operations/index.js +7 -0
- package/dist/core/install/operations/index.js.map +1 -0
- package/dist/core/install/operations/root-files.js +182 -0
- package/dist/core/install/operations/root-files.js.map +1 -0
- package/dist/core/install/path-package-loader.js +2 -1
- package/dist/core/install/path-package-loader.js.map +1 -1
- package/dist/core/install/plugin-import.js +212 -0
- package/dist/core/install/plugin-import.js.map +1 -0
- package/dist/core/install/plugin-sources.js +135 -0
- package/dist/core/install/plugin-sources.js.map +1 -0
- package/dist/core/install/plugin-transformer.js +20 -25
- package/dist/core/install/plugin-transformer.js.map +1 -1
- package/dist/core/install/sources/base.js +12 -0
- package/dist/core/install/sources/base.js.map +1 -0
- package/dist/core/install/sources/git-source.js +86 -0
- package/dist/core/install/sources/git-source.js.map +1 -0
- package/dist/core/install/sources/index.js +16 -0
- package/dist/core/install/sources/index.js.map +1 -0
- package/dist/core/install/sources/loader-factory.js +30 -0
- package/dist/core/install/sources/loader-factory.js.map +1 -0
- package/dist/core/install/sources/path-source.js +52 -0
- package/dist/core/install/sources/path-source.js.map +1 -0
- package/dist/core/install/sources/registry-source.js +47 -0
- package/dist/core/install/sources/registry-source.js.map +1 -0
- package/dist/core/install/sources/workspace-source.js +83 -0
- package/dist/core/install/sources/workspace-source.js.map +1 -0
- package/dist/core/install/strategies/base-strategy.js +101 -0
- package/dist/core/install/strategies/base-strategy.js.map +1 -0
- package/dist/core/install/strategies/conversion-strategy.js +148 -0
- package/dist/core/install/strategies/conversion-strategy.js.map +1 -0
- package/dist/core/install/strategies/direct-install-strategy.js +63 -0
- package/dist/core/install/strategies/direct-install-strategy.js.map +1 -0
- package/dist/core/install/strategies/flow-based-strategy.js +58 -0
- package/dist/core/install/strategies/flow-based-strategy.js.map +1 -0
- package/dist/core/install/strategies/helpers/flow-helpers.js +22 -0
- package/dist/core/install/strategies/helpers/flow-helpers.js.map +1 -0
- package/dist/core/install/strategies/helpers/platform-filtering.js +53 -0
- package/dist/core/install/strategies/helpers/platform-filtering.js.map +1 -0
- package/dist/core/install/strategies/helpers/result-converter.js +75 -0
- package/dist/core/install/strategies/helpers/result-converter.js.map +1 -0
- package/dist/core/install/strategies/helpers/temp-directory.js +101 -0
- package/dist/core/install/strategies/helpers/temp-directory.js.map +1 -0
- package/dist/core/install/strategies/index.js +18 -0
- package/dist/core/install/strategies/index.js.map +1 -0
- package/dist/core/install/strategies/path-mapping-strategy.js +64 -0
- package/dist/core/install/strategies/path-mapping-strategy.js.map +1 -0
- package/dist/core/install/strategies/strategy-selector.js +51 -0
- package/dist/core/install/strategies/strategy-selector.js.map +1 -0
- package/dist/core/install/strategies/types.js +7 -0
- package/dist/core/install/strategies/types.js.map +1 -0
- package/dist/core/install/unified/context-builders.js +296 -0
- package/dist/core/install/unified/context-builders.js.map +1 -0
- package/dist/core/install/unified/context-helpers.js +80 -0
- package/dist/core/install/unified/context-helpers.js.map +1 -0
- package/dist/core/install/unified/context.js +2 -0
- package/dist/core/install/unified/context.js.map +1 -0
- package/dist/core/install/unified/index.js +20 -0
- package/dist/core/install/unified/index.js.map +1 -0
- package/dist/core/install/unified/phases/conflicts.js +19 -0
- package/dist/core/install/unified/phases/conflicts.js.map +1 -0
- package/dist/core/install/unified/phases/execute.js +42 -0
- package/dist/core/install/unified/phases/execute.js.map +1 -0
- package/dist/core/install/unified/phases/load-package.js +64 -0
- package/dist/core/install/unified/phases/load-package.js.map +1 -0
- package/dist/core/install/unified/phases/manifest.js +57 -0
- package/dist/core/install/unified/phases/manifest.js.map +1 -0
- package/dist/core/install/unified/phases/report.js +29 -0
- package/dist/core/install/unified/phases/report.js.map +1 -0
- package/dist/core/install/unified/phases/resolve-dependencies.js +50 -0
- package/dist/core/install/unified/phases/resolve-dependencies.js.map +1 -0
- package/dist/core/install/unified/pipeline.js +89 -0
- package/dist/core/install/unified/pipeline.js.map +1 -0
- package/dist/core/package.js +9 -14
- package/dist/core/package.js.map +1 -1
- package/dist/core/platforms.js +111 -29
- package/dist/core/platforms.js.map +1 -1
- package/dist/core/remove/remove-from-source-pipeline.js +124 -43
- package/dist/core/remove/remove-from-source-pipeline.js.map +1 -1
- package/dist/core/save/flow-based-saver.js +6 -3
- package/dist/core/save/flow-based-saver.js.map +1 -1
- package/dist/core/status/status-comparison.js +177 -0
- package/dist/core/status/status-comparison.js.map +1 -0
- package/dist/core/status/status-file-discovery.js +2 -2
- package/dist/core/status/status-file-discovery.js.map +1 -1
- package/dist/core/status/status-hints.js +64 -0
- package/dist/core/status/status-hints.js.map +1 -0
- package/dist/core/status/status-operation-detector.js +23 -0
- package/dist/core/status/status-operation-detector.js.map +1 -0
- package/dist/core/status/status-output.js +147 -0
- package/dist/core/status/status-output.js.map +1 -0
- package/dist/core/status/status-pipeline.js +87 -78
- package/dist/core/status/status-pipeline.js.map +1 -1
- package/dist/core/status/status-source-analyzer.js +102 -0
- package/dist/core/status/status-source-analyzer.js.map +1 -0
- package/dist/core/status/status-state-classifier.js +77 -0
- package/dist/core/status/status-state-classifier.js.map +1 -0
- package/dist/core/status/status-types.js +5 -0
- package/dist/core/status/status-types.js.map +1 -0
- package/dist/core/sync/platform-sync.js +2 -2
- package/dist/core/sync/platform-sync.js.map +1 -1
- package/dist/core/uninstall/flow-aware-uninstaller.js +1 -1
- package/dist/core/uninstall/flow-aware-uninstaller.js.map +1 -1
- package/dist/core/uninstall/uninstall-pipeline.js +43 -14
- package/dist/core/uninstall/uninstall-pipeline.js.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/dist/types/conversion-context.js +11 -0
- package/dist/types/conversion-context.js.map +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/utils/directory-preservation.js +99 -0
- package/dist/utils/directory-preservation.js.map +1 -0
- package/dist/utils/file-walker.js +144 -0
- package/dist/utils/file-walker.js.map +1 -0
- package/dist/utils/flow-index-installer.js +47 -44
- package/dist/utils/flow-index-installer.js.map +1 -1
- package/dist/utils/glob-target-mapping.js +83 -0
- package/dist/utils/glob-target-mapping.js.map +1 -0
- package/dist/utils/index-based-installer.js +6 -45
- package/dist/utils/index-based-installer.js.map +1 -1
- package/dist/utils/install-helpers.js +0 -19
- package/dist/utils/install-helpers.js.map +1 -1
- package/dist/utils/logger.js +8 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/markdown-frontmatter.js +4 -2
- package/dist/utils/markdown-frontmatter.js.map +1 -1
- package/dist/utils/package-management.js +7 -0
- package/dist/utils/package-management.js.map +1 -1
- package/dist/utils/package-versioning.js +1 -1
- package/dist/utils/package-versioning.js.map +1 -1
- package/dist/utils/package-yml.js +1 -0
- package/dist/utils/package-yml.js.map +1 -1
- package/dist/utils/path-comparison.js +110 -0
- package/dist/utils/path-comparison.js.map +1 -0
- package/dist/utils/path-resolution.js +11 -7
- package/dist/utils/path-resolution.js.map +1 -1
- package/dist/utils/platform-mapper.js +134 -4
- package/dist/utils/platform-mapper.js.map +1 -1
- package/dist/utils/resolution-mode.js +16 -0
- package/dist/utils/resolution-mode.js.map +1 -0
- package/package.json +1 -1
- package/plans/conversion-context-architecture.md +695 -0
- package/plans/conversion-context-implementation-guide.md +1327 -0
- package/platforms.jsonc +319 -47
- package/schemas/agent-frontmatter-v1.json +250 -0
- package/schemas/platforms-v1.json +25 -9
- package/specs/add/README.md +107 -7
- package/specs/agents-frontmatter.md +967 -0
- package/specs/apply/apply-behavior.md +45 -1
- package/specs/apply/apply-command.md +5 -1
- package/specs/claude-plugins-marketplace-creation.md +564 -0
- package/specs/claude-settings.md +945 -0
- package/specs/cli-options.md +82 -0
- package/specs/commands-overview.md +17 -8
- package/specs/install/README.md +10 -1
- package/specs/install/install-behavior.md +118 -2
- package/specs/install/marketplace-installation.md +839 -0
- package/specs/install/plugin-installation.md +598 -0
- package/specs/install/plugin-source-normalization.md +773 -0
- package/specs/opencode-tools.md +345 -0
- package/specs/platforms/flow-reference.md +103 -0
- package/specs/platforms/flows.md +28 -2
- package/specs/remove/README.md +128 -20
- package/specs/uninstall/README.md +22 -3
package/dist/commands/add.js
CHANGED
|
@@ -2,12 +2,59 @@ import { withErrorHandling } from '../utils/errors.js';
|
|
|
2
2
|
import { runAddToSourcePipeline } from '../core/add/add-to-source-pipeline.js';
|
|
3
3
|
import { readWorkspaceIndex } from '../utils/workspace-index-yml.js';
|
|
4
4
|
import { formatPathForDisplay } from '../utils/formatters.js';
|
|
5
|
+
/**
|
|
6
|
+
* Display add operation results in install-style format
|
|
7
|
+
*/
|
|
8
|
+
function displayAddResults(data, options) {
|
|
9
|
+
const cwd = process.cwd();
|
|
10
|
+
const { filesAdded, sourcePath, sourceType, packageName: resolvedName, addedFilePaths } = data;
|
|
11
|
+
// Determine if this is a workspace root add
|
|
12
|
+
const displayPath = formatPathForDisplay(sourcePath, cwd);
|
|
13
|
+
const isWorkspaceRoot = displayPath.includes('.openpackage') && !displayPath.includes('.openpackage/packages');
|
|
14
|
+
// Main success message
|
|
15
|
+
if (isWorkspaceRoot) {
|
|
16
|
+
console.log(`ā Added to workspace package`);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
console.log(`ā Added to ${resolvedName}`);
|
|
20
|
+
}
|
|
21
|
+
// Display added files in install-style format
|
|
22
|
+
if (addedFilePaths && addedFilePaths.length > 0) {
|
|
23
|
+
console.log(`ā Added files: ${addedFilePaths.length}`);
|
|
24
|
+
const sortedFiles = [...addedFilePaths].sort((a, b) => a.localeCompare(b));
|
|
25
|
+
for (const file of sortedFiles) {
|
|
26
|
+
console.log(` āāā ${formatPathForDisplay(file, cwd)}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
console.log(`ā Added files: ${filesAdded}`);
|
|
31
|
+
}
|
|
32
|
+
// Show hints only for non-workspace-root adds
|
|
33
|
+
if (!options.apply && !isWorkspaceRoot) {
|
|
34
|
+
// Check if package is installed in workspace
|
|
35
|
+
readWorkspaceIndex(cwd).then(workspaceIndexRecord => {
|
|
36
|
+
const isInstalled = !!workspaceIndexRecord.index.packages[resolvedName];
|
|
37
|
+
if (isInstalled) {
|
|
38
|
+
console.log(`\nš” Changes not synced to workspace.`);
|
|
39
|
+
console.log(` To sync changes, run:`);
|
|
40
|
+
console.log(` opkg apply ${resolvedName}`);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
console.log(`\nš” Package not installed in workspace.`);
|
|
44
|
+
console.log(` To install and sync, run:`);
|
|
45
|
+
console.log(` opkg install ${resolvedName}`);
|
|
46
|
+
}
|
|
47
|
+
}).catch(() => {
|
|
48
|
+
// Ignore errors reading workspace index
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
5
52
|
export function setupAddCommand(program) {
|
|
6
53
|
program
|
|
7
54
|
.command('add')
|
|
8
|
-
.argument('
|
|
9
|
-
.argument('
|
|
10
|
-
.description('Add files to a mutable package source')
|
|
55
|
+
.argument('[package-name]', 'package name (optional - defaults to workspace package)')
|
|
56
|
+
.argument('[path]', 'file or directory to add')
|
|
57
|
+
.description('Add files to a mutable package source or workspace package')
|
|
11
58
|
.option('--platform-specific', 'Save platform-specific variants for platform subdir inputs')
|
|
12
59
|
.option('--apply', 'Apply changes to workspace immediately (requires package to be installed)')
|
|
13
60
|
.action(withErrorHandling(async (packageName, pathArg, options) => {
|
|
@@ -15,30 +62,9 @@ export function setupAddCommand(program) {
|
|
|
15
62
|
if (!result.success) {
|
|
16
63
|
throw new Error(result.error || 'Add operation failed');
|
|
17
64
|
}
|
|
18
|
-
//
|
|
65
|
+
// Display results
|
|
19
66
|
if (result.data) {
|
|
20
|
-
|
|
21
|
-
const { filesAdded, sourcePath, sourceType, packageName: resolvedName } = result.data;
|
|
22
|
-
// Format the path for display using unified formatter
|
|
23
|
-
const displayPath = formatPathForDisplay(sourcePath, cwd);
|
|
24
|
-
console.log(`\nā Added ${filesAdded} file${filesAdded !== 1 ? 's' : ''} to ${resolvedName}`);
|
|
25
|
-
console.log(` Path: ${displayPath}`);
|
|
26
|
-
console.log(` Type: ${sourceType} package`);
|
|
27
|
-
if (!options.apply) {
|
|
28
|
-
// Check if package is installed in workspace
|
|
29
|
-
const workspaceIndexRecord = await readWorkspaceIndex(cwd);
|
|
30
|
-
const isInstalled = !!workspaceIndexRecord.index.packages[resolvedName];
|
|
31
|
-
if (isInstalled) {
|
|
32
|
-
console.log(`\nš” Changes not synced to workspace.`);
|
|
33
|
-
console.log(` To sync changes, run:`);
|
|
34
|
-
console.log(` opkg apply ${resolvedName}`);
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
console.log(`\nš” Package not installed in workspace.`);
|
|
38
|
-
console.log(` To install and sync, run:`);
|
|
39
|
-
console.log(` opkg install ${resolvedName}`);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
67
|
+
displayAddResults(result.data, options);
|
|
42
68
|
}
|
|
43
69
|
}));
|
|
44
70
|
}
|
package/dist/commands/add.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,sBAAsB,
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/apply.js
CHANGED
|
@@ -1,16 +1,55 @@
|
|
|
1
1
|
import { withErrorHandling } from '../utils/errors.js';
|
|
2
|
-
import {
|
|
2
|
+
import { buildApplyContext } from '../core/install/unified/context-builders.js';
|
|
3
|
+
import { runUnifiedInstallPipeline } from '../core/install/unified/pipeline.js';
|
|
4
|
+
/**
|
|
5
|
+
* Main apply command handler
|
|
6
|
+
*/
|
|
7
|
+
async function applyCommand(packageName, options) {
|
|
8
|
+
const cwd = process.cwd();
|
|
9
|
+
// Handle bulk apply when no package name specified
|
|
10
|
+
if (!packageName) {
|
|
11
|
+
const contexts = await buildApplyContext(cwd, undefined, options);
|
|
12
|
+
return await applyBulk(contexts);
|
|
13
|
+
}
|
|
14
|
+
// Apply single package
|
|
15
|
+
const ctx = await buildApplyContext(cwd, packageName, options);
|
|
16
|
+
return await runUnifiedInstallPipeline(ctx);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Apply multiple packages (workspace root + all installed packages)
|
|
20
|
+
*/
|
|
21
|
+
async function applyBulk(contexts) {
|
|
22
|
+
if (contexts.length === 0) {
|
|
23
|
+
return {
|
|
24
|
+
success: false,
|
|
25
|
+
error: `No packages installed in this workspace.\n` +
|
|
26
|
+
`Run 'opkg install <package-name>' to install a package first.`
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
console.log(`ā Applying ${contexts.length} package${contexts.length === 1 ? '' : 's'}\n`);
|
|
30
|
+
for (const ctx of contexts) {
|
|
31
|
+
const result = await runUnifiedInstallPipeline(ctx);
|
|
32
|
+
if (!result.success) {
|
|
33
|
+
return result; // Stop on first failure
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return { success: true };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Setup apply command
|
|
40
|
+
*/
|
|
3
41
|
export function setupApplyCommand(program) {
|
|
4
42
|
program
|
|
5
43
|
.command('apply')
|
|
6
44
|
.description('Apply/sync package across platforms')
|
|
7
|
-
.argument('[package-name]', 'package name to apply (
|
|
45
|
+
.argument('[package-name]', 'package name to apply (optional - applies workspace-level files and all installed packages if not specified)')
|
|
8
46
|
.option('-f, --force', 'overwrite existing files without prompting')
|
|
9
47
|
.option('--dry-run', 'plan apply without writing files')
|
|
10
48
|
.action(withErrorHandling(async (packageName, options) => {
|
|
11
|
-
const result = await
|
|
12
|
-
if (!result.success)
|
|
49
|
+
const result = await applyCommand(packageName, options);
|
|
50
|
+
if (!result.success) {
|
|
13
51
|
throw new Error(result.error || 'Apply operation failed');
|
|
52
|
+
}
|
|
14
53
|
}));
|
|
15
54
|
}
|
|
16
55
|
//# sourceMappingURL=apply.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/commands/apply.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/commands/apply.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAChF,OAAO,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAEhF;;GAEG;AACH,KAAK,UAAU,YAAY,CACzB,WAA+B,EAC/B,OAA8C;IAE9C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,mDAAmD;IACnD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAClE,OAAO,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,uBAAuB;IACvB,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/D,OAAO,MAAM,yBAAyB,CAAC,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,SAAS,CAAC,QAA+B;IACtD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EACH,4CAA4C;gBAC5C,+DAA+D;SAClE,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,cAAc,QAAQ,CAAC,MAAM,WAAW,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAE1F,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,GAAG,CAAC,CAAC;QAEpD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,MAAM,CAAC,CAAC,wBAAwB;QACzC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAgB;IAChD,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,qCAAqC,CAAC;SAClD,QAAQ,CACP,gBAAgB,EAChB,8GAA8G,CAC/G;SACA,MAAM,CAAC,aAAa,EAAE,4CAA4C,CAAC;SACnE,MAAM,CAAC,WAAW,EAAE,kCAAkC,CAAC;SACvD,MAAM,CACL,iBAAiB,CAAC,KAAK,EAAE,WAA+B,EAAE,OAAY,EAAE,EAAE;QACxE,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAExD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,wBAAwB,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC,CAAC,CACH,CAAC;AACN,CAAC"}
|
package/dist/commands/install.js
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { formatPathForDisplay } from '../utils/formatters.js';
|
|
3
|
-
import { DIR_PATTERNS, PACKAGE_PATHS } from '../constants/index.js';
|
|
4
|
-
import { runBulkInstallPipeline } from '../core/install/bulk-install-pipeline.js';
|
|
5
|
-
import { runInstallPipeline, determineResolutionMode } from '../core/install/install-pipeline.js';
|
|
6
|
-
import { runPathInstallPipeline } from '../core/install/path-install-pipeline.js';
|
|
7
|
-
import { loadPackageFromGit } from '../core/install/git-package-loader.js';
|
|
8
|
-
import { inferSourceType } from '../core/install/path-package-loader.js';
|
|
9
|
-
import { detectPluginType } from '../core/install/plugin-detector.js';
|
|
10
|
-
import { parseMarketplace, promptPluginSelection, installMarketplacePlugins } from '../core/install/marketplace-handler.js';
|
|
11
|
-
import { withErrorHandling, ValidationError } from '../utils/errors.js';
|
|
1
|
+
import { withErrorHandling } from '../utils/errors.js';
|
|
12
2
|
import { normalizePlatforms } from '../utils/platform-mapper.js';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
3
|
+
import { buildInstallContext } from '../core/install/unified/context-builders.js';
|
|
4
|
+
import { runUnifiedInstallPipeline } from '../core/install/unified/pipeline.js';
|
|
5
|
+
import { determineResolutionMode } from '../utils/resolution-mode.js';
|
|
6
|
+
import { DIR_PATTERNS, PACKAGE_PATHS } from '../constants/index.js';
|
|
16
7
|
import { normalizePathForProcessing } from '../utils/path-normalization.js';
|
|
8
|
+
import { getLoaderForSource } from '../core/install/sources/loader-factory.js';
|
|
9
|
+
/**
|
|
10
|
+
* Validate that target directory is not inside .openpackage metadata
|
|
11
|
+
*/
|
|
17
12
|
function assertTargetDirOutsideMetadata(targetDir) {
|
|
18
13
|
const normalized = normalizePathForProcessing(targetDir ?? '.');
|
|
19
14
|
if (!normalized || normalized === '.') {
|
|
@@ -21,204 +16,150 @@ function assertTargetDirOutsideMetadata(targetDir) {
|
|
|
21
16
|
}
|
|
22
17
|
if (normalized === DIR_PATTERNS.OPENPACKAGE ||
|
|
23
18
|
normalized.startsWith(`${DIR_PATTERNS.OPENPACKAGE}/`)) {
|
|
24
|
-
throw new Error(`Installation target '${targetDir}' cannot point inside ${DIR_PATTERNS.OPENPACKAGE}
|
|
19
|
+
throw new Error(`Installation target '${targetDir}' cannot point inside ${DIR_PATTERNS.OPENPACKAGE} ` +
|
|
20
|
+
`(reserved for metadata like ${PACKAGE_PATHS.INDEX_RELATIVE}). ` +
|
|
21
|
+
`Choose a workspace path outside metadata.`);
|
|
25
22
|
}
|
|
26
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Validate resolution flags
|
|
26
|
+
*/
|
|
27
27
|
export function validateResolutionFlags(options) {
|
|
28
28
|
if (options.remote && options.local) {
|
|
29
29
|
throw new Error('--remote and --local cannot be used together. Choose one resolution mode.');
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Main install command handler
|
|
34
|
+
*/
|
|
32
35
|
async function installCommand(packageInput, options) {
|
|
33
|
-
const targetDir = '.';
|
|
34
36
|
const cwd = process.cwd();
|
|
37
|
+
const targetDir = '.';
|
|
38
|
+
// Validate inputs
|
|
35
39
|
assertTargetDirOutsideMetadata(targetDir);
|
|
40
|
+
validateResolutionFlags(options);
|
|
41
|
+
// Set resolution mode
|
|
36
42
|
options.resolutionMode = determineResolutionMode(options);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
43
|
+
// Build context(s)
|
|
44
|
+
const contexts = await buildInstallContext(cwd, packageInput, options);
|
|
45
|
+
// Handle bulk install (multiple contexts)
|
|
46
|
+
if (Array.isArray(contexts)) {
|
|
47
|
+
return await runBulkInstall(contexts);
|
|
40
48
|
}
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
subdirectory: existingSource.subdirectory
|
|
56
|
-
});
|
|
57
|
-
if (result.isMarketplace) {
|
|
58
|
-
throw new ValidationError(`Package '${classification.name}' is declared as a git source in openpackage.yml, ` +
|
|
59
|
-
`but the repository is a Claude Code plugin marketplace. ` +
|
|
60
|
-
`Marketplaces cannot be used as dependencies via openpackage.yml.`);
|
|
61
|
-
}
|
|
62
|
-
return await runPathInstallPipeline({
|
|
63
|
-
...options,
|
|
64
|
-
sourcePath: result.sourcePath,
|
|
65
|
-
sourceType: 'directory',
|
|
66
|
-
targetDir,
|
|
67
|
-
gitUrl: existingSource.url,
|
|
68
|
-
gitRef: existingSource.ref,
|
|
69
|
-
gitSubdirectory: existingSource.subdirectory
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
else if (existingSource.type === 'path') {
|
|
73
|
-
logger.info(`Using path source from openpackage.yml for '${classification.name}': ${existingSource.path}`);
|
|
74
|
-
const displayPath = formatPathForDisplay(existingSource.path, cwd);
|
|
75
|
-
console.log(`ā Using path source from openpackage.yml: ${displayPath}`);
|
|
76
|
-
const resolvedPath = resolve(cwd, existingSource.path);
|
|
77
|
-
const sourceType = inferSourceType(existingSource.path);
|
|
78
|
-
return await runPathInstallPipeline({
|
|
79
|
-
...options,
|
|
80
|
-
sourcePath: resolvedPath,
|
|
81
|
-
sourceType,
|
|
82
|
-
targetDir
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (classification.type === 'git') {
|
|
88
|
-
const result = await loadPackageFromGit({
|
|
89
|
-
url: classification.gitUrl,
|
|
90
|
-
ref: classification.gitRef,
|
|
91
|
-
subdirectory: classification.gitSubdirectory
|
|
92
|
-
});
|
|
93
|
-
// Check if this is a marketplace
|
|
94
|
-
if (result.isMarketplace) {
|
|
95
|
-
logger.info('Detected Claude Code marketplace, prompting for plugin selection', {
|
|
96
|
-
url: classification.gitUrl
|
|
97
|
-
});
|
|
98
|
-
const pluginDetection = await detectPluginType(result.sourcePath);
|
|
99
|
-
if (!pluginDetection.manifestPath) {
|
|
100
|
-
throw new ValidationError('Marketplace manifest not found');
|
|
101
|
-
}
|
|
102
|
-
// Parse marketplace and prompt for selection (pass context for fallback naming)
|
|
103
|
-
const marketplace = await parseMarketplace(pluginDetection.manifestPath, {
|
|
104
|
-
gitUrl: classification.gitUrl,
|
|
105
|
-
repoPath: result.repoPath
|
|
106
|
-
});
|
|
107
|
-
const selectedPlugins = await promptPluginSelection(marketplace);
|
|
108
|
-
if (selectedPlugins.length === 0) {
|
|
109
|
-
console.log('No plugins selected. Installation cancelled.');
|
|
110
|
-
return { success: true };
|
|
111
|
-
}
|
|
112
|
-
// Install selected plugins
|
|
113
|
-
return await installMarketplacePlugins(result.repoPath, marketplace, selectedPlugins, classification.gitUrl, classification.gitRef, options);
|
|
49
|
+
// For git sources, we need to load the package first to detect if it's a marketplace
|
|
50
|
+
// Marketplaces are detected during loadPackagePhase, so we need to check after loading
|
|
51
|
+
if (contexts.source.type === 'git') {
|
|
52
|
+
// Load package to detect marketplace
|
|
53
|
+
const loader = getLoaderForSource(contexts.source);
|
|
54
|
+
const loaded = await loader.load(contexts.source, options, cwd);
|
|
55
|
+
// Update context with loaded info
|
|
56
|
+
contexts.source.packageName = loaded.packageName;
|
|
57
|
+
contexts.source.version = loaded.version;
|
|
58
|
+
contexts.source.contentRoot = loaded.contentRoot;
|
|
59
|
+
contexts.source.pluginMetadata = loaded.pluginMetadata;
|
|
60
|
+
// Check if marketplace - handle at command level
|
|
61
|
+
if (contexts.source.pluginMetadata?.pluginType === 'marketplace') {
|
|
62
|
+
return await handleMarketplaceInstallation(contexts, options, cwd);
|
|
114
63
|
}
|
|
115
|
-
// Not a marketplace,
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
64
|
+
// Not a marketplace, continue with normal pipeline
|
|
65
|
+
// Create resolved package for the loaded package
|
|
66
|
+
contexts.resolvedPackages = [{
|
|
67
|
+
name: loaded.packageName,
|
|
68
|
+
version: loaded.version,
|
|
69
|
+
pkg: { metadata: loaded.metadata, files: [], _format: undefined },
|
|
70
|
+
isRoot: true,
|
|
71
|
+
source: 'git',
|
|
72
|
+
contentRoot: loaded.contentRoot
|
|
73
|
+
}];
|
|
125
74
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
// Parse marketplace and prompt for selection (pass context for fallback naming)
|
|
139
|
-
const marketplace = await parseMarketplace(pluginDetection.manifestPath, {
|
|
140
|
-
repoPath: classification.resolvedPath
|
|
141
|
-
});
|
|
142
|
-
const selectedPlugins = await promptPluginSelection(marketplace);
|
|
143
|
-
if (selectedPlugins.length === 0) {
|
|
144
|
-
console.log('No plugins selected. Installation cancelled.');
|
|
145
|
-
return { success: true };
|
|
146
|
-
}
|
|
147
|
-
// Install selected plugins (no git URL for local paths)
|
|
148
|
-
return await installMarketplacePlugins(classification.resolvedPath, marketplace, selectedPlugins, classification.resolvedPath, // Use path as "url" for tracking
|
|
149
|
-
undefined, // No git ref for local paths
|
|
150
|
-
options);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return await runPathInstallPipeline({
|
|
154
|
-
...options,
|
|
155
|
-
sourcePath: classification.resolvedPath,
|
|
156
|
-
sourceType: classification.type,
|
|
157
|
-
targetDir
|
|
158
|
-
});
|
|
75
|
+
// Single package install
|
|
76
|
+
return await runUnifiedInstallPipeline(contexts);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Handle marketplace installation with plugin selection
|
|
80
|
+
*/
|
|
81
|
+
async function handleMarketplaceInstallation(context, options, cwd) {
|
|
82
|
+
const { parseMarketplace, promptPluginSelection, installMarketplacePlugins } = await import('../core/install/marketplace-handler.js');
|
|
83
|
+
const { Spinner } = await import('../utils/spinner.js');
|
|
84
|
+
// Load the marketplace package (already loaded, use context data)
|
|
85
|
+
if (!context.source.pluginMetadata?.manifestPath) {
|
|
86
|
+
throw new Error('Marketplace manifest not found');
|
|
159
87
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
version,
|
|
166
|
-
registryPath,
|
|
167
|
-
targetDir
|
|
88
|
+
const spinner = new Spinner('Loading marketplace');
|
|
89
|
+
spinner.start();
|
|
90
|
+
// Parse marketplace manifest
|
|
91
|
+
const marketplace = await parseMarketplace(context.source.pluginMetadata.manifestPath, {
|
|
92
|
+
repoPath: context.source.contentRoot
|
|
168
93
|
});
|
|
94
|
+
spinner.stop();
|
|
95
|
+
// Prompt user to select plugins
|
|
96
|
+
const selectedPlugins = await promptPluginSelection(marketplace);
|
|
97
|
+
if (selectedPlugins.length === 0) {
|
|
98
|
+
console.log('No plugins selected. Installation cancelled.');
|
|
99
|
+
return { success: true, data: { installed: 0, skipped: 0 } };
|
|
100
|
+
}
|
|
101
|
+
// Install selected plugins using marketplace handler
|
|
102
|
+
// At this point we know it's a git source with a gitUrl
|
|
103
|
+
if (context.source.type !== 'git' || !context.source.gitUrl) {
|
|
104
|
+
throw new Error('Marketplace must be from a git source');
|
|
105
|
+
}
|
|
106
|
+
return await installMarketplacePlugins(context.source.contentRoot, marketplace, selectedPlugins, context.source.gitUrl, context.source.gitRef, options, cwd);
|
|
169
107
|
}
|
|
170
108
|
/**
|
|
171
|
-
*
|
|
109
|
+
* Run bulk installation for multiple packages
|
|
172
110
|
*/
|
|
173
|
-
function
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
console.log(
|
|
178
|
-
console.log(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
// Single source - simple message
|
|
182
|
-
if (reason === 'only-source' && candidates.length === 1) {
|
|
183
|
-
const sourceType = selected.type === 'global' ? 'global packages' :
|
|
184
|
-
selected.type === 'registry' ? 'registry' : 'workspace packages';
|
|
185
|
-
console.log(`ā Found ${selected.packageName} in ${sourceType}`);
|
|
186
|
-
return;
|
|
111
|
+
async function runBulkInstall(contexts) {
|
|
112
|
+
if (contexts.length === 0) {
|
|
113
|
+
console.log('ā ļø No packages found in openpackage.yml');
|
|
114
|
+
console.log('\nš” Tips:');
|
|
115
|
+
console.log(' ⢠Add packages to the "packages" array in openpackage.yml');
|
|
116
|
+
console.log(' ⢠Add development packages to the "dev-packages" array');
|
|
117
|
+
console.log(' ⢠Use "opkg install <package-name>" to install a specific package');
|
|
118
|
+
return { success: true, data: { installed: 0, skipped: 0 } };
|
|
187
119
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
console.log(`š” To update global: cd ~/.openpackage/packages/${selected.packageName} && opkg pack`);
|
|
205
|
-
}
|
|
120
|
+
console.log(`\nā Installing ${contexts.length} package${contexts.length === 1 ? '' : 's'} from openpackage.yml\n`);
|
|
121
|
+
let totalInstalled = 0;
|
|
122
|
+
let totalSkipped = 0;
|
|
123
|
+
const results = [];
|
|
124
|
+
for (const ctx of contexts) {
|
|
125
|
+
try {
|
|
126
|
+
const result = await runUnifiedInstallPipeline(ctx);
|
|
127
|
+
if (result.success) {
|
|
128
|
+
totalInstalled++;
|
|
129
|
+
results.push({ name: ctx.source.packageName, success: true });
|
|
130
|
+
console.log(`ā ${ctx.source.packageName}`);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
totalSkipped++;
|
|
134
|
+
results.push({ name: ctx.source.packageName, success: false, error: result.error });
|
|
135
|
+
console.log(`ā ${ctx.source.packageName}: ${result.error}`);
|
|
206
136
|
}
|
|
207
137
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
console.log(`ā Using ${selected.packageName}@${selected.version} from ${sourceLabel}`);
|
|
138
|
+
catch (error) {
|
|
139
|
+
totalSkipped++;
|
|
140
|
+
results.push({ name: ctx.source.packageName, success: false, error: String(error) });
|
|
141
|
+
console.log(`ā ${ctx.source.packageName}: ${error}`);
|
|
213
142
|
}
|
|
214
143
|
}
|
|
144
|
+
// Display summary
|
|
145
|
+
console.log(`\nā Installation complete: ${totalInstalled} installed${totalSkipped > 0 ? `, ${totalSkipped} failed` : ''}`);
|
|
146
|
+
const allSuccessful = totalSkipped === 0;
|
|
147
|
+
return {
|
|
148
|
+
success: allSuccessful,
|
|
149
|
+
data: { installed: totalInstalled, skipped: totalSkipped, results },
|
|
150
|
+
error: allSuccessful ? undefined : `${totalSkipped} packages failed to install`
|
|
151
|
+
};
|
|
215
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Setup install command
|
|
155
|
+
*/
|
|
216
156
|
export function setupInstallCommand(program) {
|
|
217
157
|
program
|
|
218
158
|
.command('install')
|
|
219
159
|
.alias('i')
|
|
220
160
|
.description('Install packages to workspace')
|
|
221
|
-
.argument('[package-name]', 'name of the package to install (optional - installs all from openpackage.yml if not specified).
|
|
161
|
+
.argument('[package-name]', 'name of the package to install (optional - installs workspace-level files and all packages from openpackage.yml if not specified). ' +
|
|
162
|
+
'Supports package@version syntax.')
|
|
222
163
|
.option('--dry-run', 'preview changes without applying them')
|
|
223
164
|
.option('--force', 'overwrite existing files')
|
|
224
165
|
.option('--conflicts <strategy>', 'conflict handling strategy: keep-both, overwrite, skip, or ask')
|
|
@@ -229,23 +170,27 @@ export function setupInstallCommand(program) {
|
|
|
229
170
|
.option('--profile <profile>', 'profile to use for authentication')
|
|
230
171
|
.option('--api-key <key>', 'API key for authentication (overrides profile)')
|
|
231
172
|
.action(withErrorHandling(async (packageName, options) => {
|
|
173
|
+
// Normalize platforms
|
|
232
174
|
options.platforms = normalizePlatforms(options.platforms);
|
|
175
|
+
// Normalize conflict strategy
|
|
233
176
|
const commandOptions = options;
|
|
234
177
|
const rawConflictStrategy = commandOptions.conflicts ?? options.conflictStrategy;
|
|
235
178
|
if (rawConflictStrategy) {
|
|
236
179
|
const normalizedStrategy = rawConflictStrategy.toLowerCase();
|
|
237
|
-
const allowedStrategies = [
|
|
180
|
+
const allowedStrategies = [
|
|
181
|
+
'keep-both', 'overwrite', 'skip', 'ask'
|
|
182
|
+
];
|
|
238
183
|
if (!allowedStrategies.includes(normalizedStrategy)) {
|
|
239
|
-
throw new Error(`Invalid --conflicts value '${rawConflictStrategy}'.
|
|
184
|
+
throw new Error(`Invalid --conflicts value '${rawConflictStrategy}'. ` +
|
|
185
|
+
`Use one of: keep-both, overwrite, skip, ask.`);
|
|
240
186
|
}
|
|
241
187
|
options.conflictStrategy = normalizedStrategy;
|
|
242
188
|
}
|
|
243
|
-
|
|
244
|
-
options.resolutionMode = determineResolutionMode(options);
|
|
189
|
+
// Execute install
|
|
245
190
|
const result = await installCommand(packageName, options);
|
|
246
191
|
if (!result.success) {
|
|
247
192
|
if (result.error === 'Package not found') {
|
|
248
|
-
return;
|
|
193
|
+
return; // Already displayed message
|
|
249
194
|
}
|
|
250
195
|
throw new Error(result.error || 'Installation operation failed');
|
|
251
196
|
}
|