opkg 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -186
- package/assets/openpackage_ascii_dark.png +0 -0
- package/assets/openpackage_ascii_light.png +0 -0
- package/dist/commands/add.js +34 -10
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/apply.js +16 -0
- package/dist/commands/apply.js.map +1 -0
- package/dist/commands/delete.js +1 -1
- package/dist/commands/delete.js.map +1 -1
- package/dist/commands/install.js +177 -8
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/list.js +2 -2
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/login.js +1 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +1 -1
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/new.js +125 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/pack.js +7 -13
- package/dist/commands/pack.js.map +1 -1
- package/dist/commands/pull.js +1 -1
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/push.js +1 -1
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/remove.js +63 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/save.js +11 -17
- package/dist/commands/save.js.map +1 -1
- package/dist/commands/set.js +33 -0
- package/dist/commands/set.js.map +1 -0
- package/dist/commands/show.js +16 -94
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/status.js +26 -701
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/uninstall.js +14 -427
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/constants/index.js +72 -16
- package/dist/constants/index.js.map +1 -1
- package/dist/core/add/add-conflict-handler.js +1 -8
- package/dist/core/add/add-conflict-handler.js.map +1 -1
- package/dist/core/add/add-pipeline.js +12 -10
- package/dist/core/add/add-pipeline.js.map +1 -1
- package/dist/core/add/add-to-source-pipeline.js +123 -0
- package/dist/core/add/add-to-source-pipeline.js.map +1 -0
- package/dist/core/add/package-index-updater.js +77 -78
- package/dist/core/add/package-index-updater.js.map +1 -1
- package/dist/core/add/platform-path-transformer.js +6 -4
- package/dist/core/add/platform-path-transformer.js.map +1 -1
- package/dist/core/add/source-collector.js +2 -3
- package/dist/core/add/source-collector.js.map +1 -1
- package/dist/core/apply/apply-pipeline.js +110 -0
- package/dist/core/apply/apply-pipeline.js.map +1 -0
- package/dist/core/dependency-resolver.js +263 -21
- package/dist/core/dependency-resolver.js.map +1 -1
- package/dist/core/discovery/file-discovery.js +1 -2
- package/dist/core/discovery/file-discovery.js.map +1 -1
- package/dist/core/discovery/platform-files-discovery.js +33 -18
- package/dist/core/discovery/platform-files-discovery.js.map +1 -1
- package/dist/core/flows/flow-executor.js +974 -0
- package/dist/core/flows/flow-executor.js.map +1 -0
- package/dist/core/flows/flow-inverter.js +442 -0
- package/dist/core/flows/flow-inverter.js.map +1 -0
- package/dist/core/flows/flow-key-extractor.js +101 -0
- package/dist/core/flows/flow-key-extractor.js.map +1 -0
- package/dist/core/flows/flow-key-mapper.js +382 -0
- package/dist/core/flows/flow-key-mapper.js.map +1 -0
- package/dist/core/flows/flow-transforms.js +632 -0
- package/dist/core/flows/flow-transforms.js.map +1 -0
- package/dist/core/flows/map-pipeline/context.js +73 -0
- package/dist/core/flows/map-pipeline/context.js.map +1 -0
- package/dist/core/flows/map-pipeline/index.js +156 -0
- package/dist/core/flows/map-pipeline/index.js.map +1 -0
- package/dist/core/flows/map-pipeline/operations/copy.js +104 -0
- package/dist/core/flows/map-pipeline/operations/copy.js.map +1 -0
- package/dist/core/flows/map-pipeline/operations/pipe.js +70 -0
- package/dist/core/flows/map-pipeline/operations/pipe.js.map +1 -0
- package/dist/core/flows/map-pipeline/operations/rename.js +102 -0
- package/dist/core/flows/map-pipeline/operations/rename.js.map +1 -0
- package/dist/core/flows/map-pipeline/operations/set.js +50 -0
- package/dist/core/flows/map-pipeline/operations/set.js.map +1 -0
- package/dist/core/flows/map-pipeline/operations/switch.js +79 -0
- package/dist/core/flows/map-pipeline/operations/switch.js.map +1 -0
- package/dist/core/flows/map-pipeline/operations/transform.js +543 -0
- package/dist/core/flows/map-pipeline/operations/transform.js.map +1 -0
- package/dist/core/flows/map-pipeline/operations/unset.js +65 -0
- package/dist/core/flows/map-pipeline/operations/unset.js.map +1 -0
- package/dist/core/flows/map-pipeline/types.js +8 -0
- package/dist/core/flows/map-pipeline/types.js.map +1 -0
- package/dist/core/flows/map-pipeline/utils.js +278 -0
- package/dist/core/flows/map-pipeline/utils.js.map +1 -0
- package/dist/core/flows/platform-converter.js +328 -0
- package/dist/core/flows/platform-converter.js.map +1 -0
- package/dist/core/flows/source-resolver.js +192 -0
- package/dist/core/flows/source-resolver.js.map +1 -0
- package/dist/core/flows/toml-domain-transforms.js +23 -0
- package/dist/core/flows/toml-domain-transforms.js.map +1 -0
- package/dist/core/install/bulk-install-pipeline.js +68 -7
- package/dist/core/install/bulk-install-pipeline.js.map +1 -1
- package/dist/core/install/canonical-plan.js +3 -3
- package/dist/core/install/canonical-plan.js.map +1 -1
- package/dist/core/install/dry-run.js +3 -3
- package/dist/core/install/dry-run.js.map +1 -1
- package/dist/core/install/flow-based-installer.js +1158 -0
- package/dist/core/install/flow-based-installer.js.map +1 -0
- package/dist/core/install/flow-workspace-tracker.js +111 -0
- package/dist/core/install/flow-workspace-tracker.js.map +1 -0
- package/dist/core/install/format-detector.js +228 -0
- package/dist/core/install/format-detector.js.map +1 -0
- package/dist/core/install/git-package-loader.js +20 -0
- package/dist/core/install/git-package-loader.js.map +1 -0
- package/dist/core/install/install-errors.js +1 -1
- package/dist/core/install/install-errors.js.map +1 -1
- package/dist/core/install/install-flow.js +34 -14
- package/dist/core/install/install-flow.js.map +1 -1
- package/dist/core/install/install-pipeline.js +52 -17
- package/dist/core/install/install-pipeline.js.map +1 -1
- package/dist/core/install/install-reporting.js +26 -8
- package/dist/core/install/install-reporting.js.map +1 -1
- package/dist/core/install/local-source-resolution.js +103 -0
- package/dist/core/install/local-source-resolution.js.map +1 -0
- package/dist/core/install/marketplace-handler.js +221 -0
- package/dist/core/install/marketplace-handler.js.map +1 -0
- package/dist/core/install/path-install-pipeline.js +241 -0
- package/dist/core/install/path-install-pipeline.js.map +1 -0
- package/dist/core/install/path-package-loader.js +116 -0
- package/dist/core/install/path-package-loader.js.map +1 -0
- package/dist/core/install/plugin-detector.js +72 -0
- package/dist/core/install/plugin-detector.js.map +1 -0
- package/dist/core/install/plugin-to-universal-converter.js +218 -0
- package/dist/core/install/plugin-to-universal-converter.js.map +1 -0
- package/dist/core/install/plugin-transformer.js +191 -0
- package/dist/core/install/plugin-transformer.js.map +1 -0
- package/dist/core/install/version-selection.js +1 -1
- package/dist/core/install/version-selection.js.map +1 -1
- package/dist/core/openpackage.js +40 -22
- package/dist/core/openpackage.js.map +1 -1
- package/dist/core/pack/pack-output.js +62 -0
- package/dist/core/pack/pack-output.js.map +1 -0
- package/dist/core/pack/pack-pipeline.js +186 -0
- package/dist/core/pack/pack-pipeline.js.map +1 -0
- package/dist/core/package-context.js +45 -70
- package/dist/core/package-context.js.map +1 -1
- package/dist/core/package-creation.js +203 -0
- package/dist/core/package-creation.js.map +1 -0
- package/dist/core/package.js +20 -6
- package/dist/core/package.js.map +1 -1
- package/dist/core/platforms.js +665 -209
- package/dist/core/platforms.js.map +1 -1
- package/dist/core/push/push-context.js +1 -1
- package/dist/core/push/push-context.js.map +1 -1
- package/dist/core/push/push-upload.js +2 -2
- package/dist/core/push/push-upload.js.map +1 -1
- package/dist/core/registry.js +6 -6
- package/dist/core/registry.js.map +1 -1
- package/dist/core/remote-pull.js +2 -2
- package/dist/core/remote-pull.js.map +1 -1
- package/dist/core/remove/removal-collector.js +52 -0
- package/dist/core/remove/removal-collector.js.map +1 -0
- package/dist/core/remove/removal-confirmation.js +39 -0
- package/dist/core/remove/removal-confirmation.js.map +1 -0
- package/dist/core/remove/remove-from-source-pipeline.js +173 -0
- package/dist/core/remove/remove-from-source-pipeline.js.map +1 -0
- package/dist/core/save/constants.js +3 -3
- package/dist/core/save/constants.js.map +1 -1
- package/dist/core/save/flow-based-saver.js +270 -0
- package/dist/core/save/flow-based-saver.js.map +1 -0
- package/dist/core/save/name-resolution.js +1 -1
- package/dist/core/save/name-resolution.js.map +1 -1
- package/dist/core/save/package-yml-generator.js +4 -5
- package/dist/core/save/package-yml-generator.js.map +1 -1
- package/dist/core/save/save-candidate-builder.js +215 -0
- package/dist/core/save/save-candidate-builder.js.map +1 -0
- package/dist/core/save/save-candidate-loader.js +12 -11
- package/dist/core/save/save-candidate-loader.js.map +1 -1
- package/dist/core/save/save-conflict-analyzer.js +150 -0
- package/dist/core/save/save-conflict-analyzer.js.map +1 -0
- package/dist/core/save/save-conflict-resolution.js +28 -14
- package/dist/core/save/save-conflict-resolution.js.map +1 -1
- package/dist/core/save/save-conflict-resolver.js +31 -275
- package/dist/core/save/save-conflict-resolver.js.map +1 -1
- package/dist/core/save/save-group-builder.js +52 -0
- package/dist/core/save/save-group-builder.js.map +1 -0
- package/dist/core/save/save-interactive-resolver.js +190 -0
- package/dist/core/save/save-interactive-resolver.js.map +1 -0
- package/dist/core/save/save-pipeline.js +58 -34
- package/dist/core/save/save-pipeline.js.map +1 -1
- package/dist/core/save/save-platform-handler.js +53 -0
- package/dist/core/save/save-platform-handler.js.map +1 -0
- package/dist/core/save/save-resolution-executor.js +145 -0
- package/dist/core/save/save-resolution-executor.js.map +1 -0
- package/dist/core/save/save-result-reporter.js +167 -0
- package/dist/core/save/save-result-reporter.js.map +1 -0
- package/dist/core/save/save-to-source-pipeline.js +154 -0
- package/dist/core/save/save-to-source-pipeline.js.map +1 -0
- package/dist/core/save/save-versioning.js +4 -4
- package/dist/core/save/save-versioning.js.map +1 -1
- package/dist/core/save/save-write-coordinator.js +204 -0
- package/dist/core/save/save-write-coordinator.js.map +1 -0
- package/dist/core/save/save-yml-resolution.js +28 -216
- package/dist/core/save/save-yml-resolution.js.map +1 -1
- package/dist/core/save/workspace-rename.js +7 -8
- package/dist/core/save/workspace-rename.js.map +1 -1
- package/dist/core/set/set-output.js +72 -0
- package/dist/core/set/set-output.js.map +1 -0
- package/dist/core/set/set-pipeline.js +361 -0
- package/dist/core/set/set-pipeline.js.map +1 -0
- package/dist/core/set/set-types.js +5 -0
- package/dist/core/set/set-types.js.map +1 -0
- package/dist/core/show/package-resolver.js +257 -0
- package/dist/core/show/package-resolver.js.map +1 -0
- package/dist/core/show/scope-discovery.js +165 -0
- package/dist/core/show/scope-discovery.js.map +1 -0
- package/dist/core/show/show-output.js +168 -0
- package/dist/core/show/show-output.js.map +1 -0
- package/dist/core/show/show-pipeline.js +113 -0
- package/dist/core/show/show-pipeline.js.map +1 -0
- package/dist/core/show/show-types.js +5 -0
- package/dist/core/show/show-types.js.map +1 -0
- package/dist/core/source-resolution/dependency-graph.js +104 -0
- package/dist/core/source-resolution/dependency-graph.js.map +1 -0
- package/dist/core/source-resolution/resolve-mutable-source.js +109 -0
- package/dist/core/source-resolution/resolve-mutable-source.js.map +1 -0
- package/dist/core/source-resolution/resolve-package-source.js +29 -0
- package/dist/core/source-resolution/resolve-package-source.js.map +1 -0
- package/dist/core/source-resolution/resolve-registry-version.js +35 -0
- package/dist/core/source-resolution/resolve-registry-version.js.map +1 -0
- package/dist/core/source-resolution/types.js.map +1 -0
- package/dist/core/status/status-file-discovery.js +23 -12
- package/dist/core/status/status-file-discovery.js.map +1 -1
- package/dist/core/status/status-pipeline.js +134 -0
- package/dist/core/status/status-pipeline.js.map +1 -0
- package/dist/core/sync/platform-sync-summary.js +27 -0
- package/dist/core/sync/platform-sync-summary.js.map +1 -0
- package/dist/core/uninstall/flow-aware-uninstaller.js +189 -0
- package/dist/core/uninstall/flow-aware-uninstaller.js.map +1 -0
- package/dist/core/uninstall/uninstall-file-discovery.js +11 -6
- package/dist/core/uninstall/uninstall-file-discovery.js.map +1 -1
- package/dist/core/uninstall/uninstall-pipeline.js +141 -0
- package/dist/core/uninstall/uninstall-pipeline.js.map +1 -0
- package/dist/core/universal-patterns.js +64 -0
- package/dist/core/universal-patterns.js.map +1 -0
- package/dist/index.js +99 -6
- package/dist/index.js.map +1 -1
- package/dist/types/flows.js +8 -0
- package/dist/types/flows.js.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/platform-flows.js +8 -0
- package/dist/types/platform-flows.js.map +1 -0
- package/dist/types/workspace-index.js +6 -0
- package/dist/types/workspace-index.js.map +1 -0
- package/dist/utils/custom-path-resolution.js +160 -0
- package/dist/utils/custom-path-resolution.js.map +1 -0
- package/dist/utils/dependency-coverage.js +1 -1
- package/dist/utils/dependency-coverage.js.map +1 -1
- package/dist/utils/file-processing.js +1 -1
- package/dist/utils/flow-index-installer.js +209 -0
- package/dist/utils/flow-index-installer.js.map +1 -0
- package/dist/utils/formatters.js +47 -1
- package/dist/utils/formatters.js.map +1 -1
- package/dist/utils/fs.js +17 -0
- package/dist/utils/fs.js.map +1 -1
- package/dist/utils/git-clone-registry.js +88 -0
- package/dist/utils/git-clone-registry.js.map +1 -0
- package/dist/utils/git-clone.js +69 -0
- package/dist/utils/git-clone.js.map +1 -0
- package/dist/utils/git-spec.js +96 -0
- package/dist/utils/git-spec.js.map +1 -0
- package/dist/utils/http-client.js +7 -0
- package/dist/utils/http-client.js.map +1 -1
- package/dist/utils/index-based-installer.js +356 -163
- package/dist/utils/index-based-installer.js.map +1 -1
- package/dist/utils/install-conflict-handler.js +2 -2
- package/dist/utils/install-conflict-handler.js.map +1 -1
- package/dist/utils/install-file-discovery.js +18 -13
- package/dist/utils/install-file-discovery.js.map +1 -1
- package/dist/utils/install-helpers.js +43 -20
- package/dist/utils/install-helpers.js.map +1 -1
- package/dist/utils/jsonc.js +23 -1
- package/dist/utils/jsonc.js.map +1 -1
- package/dist/utils/manifest-paths.js +1 -1
- package/dist/utils/manifest-paths.js.map +1 -1
- package/dist/utils/markdown-frontmatter.js +46 -0
- package/dist/utils/markdown-frontmatter.js.map +1 -1
- package/dist/utils/package-copy.js +5 -103
- package/dist/utils/package-copy.js.map +1 -1
- package/dist/utils/package-filters.js +9 -105
- package/dist/utils/package-filters.js.map +1 -1
- package/dist/utils/package-index-yml.js +27 -6
- package/dist/utils/package-index-yml.js.map +1 -1
- package/dist/utils/package-input.js +98 -0
- package/dist/utils/package-input.js.map +1 -0
- package/dist/utils/package-management.js +80 -28
- package/dist/utils/package-management.js.map +1 -1
- package/dist/utils/package-name-resolution.js +327 -0
- package/dist/utils/package-name-resolution.js.map +1 -0
- package/dist/utils/package-name.js +18 -16
- package/dist/utils/package-name.js.map +1 -1
- package/dist/utils/package-versioning.js +2 -33
- package/dist/utils/package-versioning.js.map +1 -1
- package/dist/utils/package-yml.js +19 -28
- package/dist/utils/package-yml.js.map +1 -1
- package/dist/utils/path-resolution.js +102 -0
- package/dist/utils/path-resolution.js.map +1 -0
- package/dist/utils/paths.js +6 -6
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/platform-file.js +36 -24
- package/dist/utils/platform-file.js.map +1 -1
- package/dist/utils/platform-mapper.js +222 -68
- package/dist/utils/platform-mapper.js.map +1 -1
- package/dist/utils/platform-root-files.js +44 -0
- package/dist/utils/platform-root-files.js.map +1 -0
- package/dist/utils/platform-utils.js +35 -54
- package/dist/utils/platform-utils.js.map +1 -1
- package/dist/utils/platform-yaml-merge.js +20 -140
- package/dist/utils/platform-yaml-merge.js.map +1 -1
- package/dist/utils/prompts.js +92 -7
- package/dist/utils/prompts.js.map +1 -1
- package/dist/utils/registry-entry-filter.js +50 -27
- package/dist/utils/registry-entry-filter.js.map +1 -1
- package/dist/utils/registry-paths.js +5 -4
- package/dist/utils/registry-paths.js.map +1 -1
- package/dist/utils/scope-resolution.js +156 -0
- package/dist/utils/scope-resolution.js.map +1 -0
- package/dist/utils/source-mutability.js +15 -0
- package/dist/utils/source-mutability.js.map +1 -0
- package/dist/utils/tarball.js +29 -4
- package/dist/utils/tarball.js.map +1 -1
- package/dist/utils/version-ranges.js +1 -32
- package/dist/utils/version-ranges.js.map +1 -1
- package/dist/utils/workspace-index-helpers.js +28 -0
- package/dist/utils/workspace-index-helpers.js.map +1 -0
- package/dist/utils/workspace-index-ownership.js +100 -0
- package/dist/utils/workspace-index-ownership.js.map +1 -0
- package/dist/utils/workspace-index-yml.js +173 -0
- package/dist/utils/workspace-index-yml.js.map +1 -0
- package/examples/custom-subdirs-platform.jsonc +157 -0
- package/package.json +7 -2
- package/platforms.jsonc +531 -84
- package/schemas/map-pipeline-v1.json +256 -0
- package/schemas/platforms-v1.json +400 -0
- package/specs/README.md +88 -0
- package/specs/add/README.md +166 -0
- package/specs/agents-claude.md +570 -0
- package/specs/agents-opencode.md +622 -0
- package/specs/apply/README.md +21 -0
- package/specs/apply/apply-behavior.md +58 -0
- package/specs/apply/apply-command.md +51 -0
- package/specs/apply/conflicts.md +41 -0
- package/specs/apply/index-effects.md +81 -0
- package/specs/architecture.md +107 -0
- package/specs/auth/README.md +17 -0
- package/specs/auth/auth-http-contract.md +25 -0
- package/specs/auth/cli/credentials.md +39 -0
- package/specs/auth/cli/login.md +32 -0
- package/specs/auth/cli/logout.md +16 -0
- package/specs/claude-mcp.md +1065 -0
- package/specs/claude-plugins-marketplace.md +363 -0
- package/specs/claude-plugins.md +413 -0
- package/specs/cli-options.md +52 -0
- package/specs/codex-mcp.md +114 -0
- package/specs/commands-overview.md +175 -0
- package/specs/directory-layout.md +95 -0
- package/specs/install/README.md +12 -4
- package/specs/install/git-sources.md +230 -0
- package/specs/install/install-behavior.md +483 -73
- package/specs/install/package-yml-canonical.md +67 -35
- package/specs/install/version-resolution.md +69 -115
- package/specs/new/README.md +769 -0
- package/specs/new/SUMMARY.md +310 -0
- package/specs/new/scope-behavior.md +793 -0
- package/specs/pack/README.md +77 -0
- package/specs/pack/package-name-resolution.md +330 -0
- package/specs/package/README.md +18 -17
- package/specs/package/nested-packages-and-parent-packages.md +32 -31
- package/specs/package/package-index-yml.md +95 -101
- package/specs/package/package-root-layout.md +64 -46
- package/specs/package/registry-payload-and-copy.md +50 -44
- package/specs/package/universal-content.md +33 -56
- package/specs/package-sources.md +248 -0
- package/specs/platforms/README.md +52 -0
- package/specs/platforms/configuration.md +571 -0
- package/specs/platforms/detection.md +552 -0
- package/specs/platforms/directory-layout.md +599 -0
- package/specs/platforms/examples.md +1146 -0
- package/specs/platforms/flow-reference.md +1240 -0
- package/specs/platforms/flows.md +1488 -0
- package/specs/platforms/map-pipeline.md +801 -0
- package/specs/platforms/overview.md +349 -0
- package/specs/platforms/specification.md +700 -0
- package/specs/platforms/troubleshooting.md +697 -0
- package/specs/platforms/universal-converter.md +520 -0
- package/specs/push/README.md +1 -0
- package/specs/push/push-behavior.md +11 -3
- package/specs/push/push-remote-upload.md +1 -1
- package/specs/push/push-scoping.md +1 -1
- package/specs/push/push-version-selection.md +1 -1
- package/specs/registry.md +111 -0
- package/specs/remove/README.md +257 -0
- package/specs/save/README.md +21 -17
- package/specs/save/save-conflict-resolution.md +205 -83
- package/specs/save/save-file-discovery.md +6 -4
- package/specs/save/save-frontmatter-overrides.md +11 -15
- package/specs/save/save-modes-inputs.md +9 -39
- package/specs/save/save-naming-scoping.md +4 -4
- package/specs/save/save-package-detection.md +13 -13
- package/specs/save/save-registry-sync.md +16 -106
- package/specs/save/save-versioning.md +80 -0
- package/specs/scope-management.md +92 -0
- package/specs/set/README.md +520 -0
- package/specs/set/set-behavior.md +563 -0
- package/specs/show/README.md +483 -0
- package/specs/show/show-remote.md +494 -0
- package/specs/status/README.md +38 -0
- package/specs/uninstall/README.md +231 -0
- package/dist/commands/duplicate.js +0 -69
- package/dist/commands/duplicate.js.map +0 -1
- package/dist/commands/init.js +0 -117
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/prune.js +0 -357
- package/dist/commands/prune.js.map +0 -1
- package/dist/commands/tui.js +0 -61
- package/dist/commands/tui.js.map +0 -1
- package/dist/core/install/index.js +0 -3
- package/dist/core/install/index.js.map +0 -1
- package/dist/core/push/push-single-file.js +0 -56
- package/dist/core/push/push-single-file.js.map +0 -1
- package/dist/core/save/package-detection.js +0 -147
- package/dist/core/save/package-detection.js.map +0 -1
- package/dist/core/save/save-single-file.js +0 -124
- package/dist/core/save/save-single-file.js.map +0 -1
- package/dist/core/token-store.js +0 -73
- package/dist/core/token-store.js.map +0 -1
- package/dist/tui/app.js +0 -95
- package/dist/tui/app.js.map +0 -1
- package/dist/tui/components/package-list.js +0 -73
- package/dist/tui/components/package-list.js.map +0 -1
- package/dist/tui/controller.js +0 -365
- package/dist/tui/controller.js.map +0 -1
- package/dist/tui/index.js +0 -12
- package/dist/tui/index.js.map +0 -1
- package/dist/tui/services/file-index.js +0 -64
- package/dist/tui/services/file-index.js.map +0 -1
- package/dist/tui/services/packages.js +0 -18
- package/dist/tui/services/packages.js.map +0 -1
- package/dist/tui/services/save.js +0 -21
- package/dist/tui/services/save.js.map +0 -1
- package/dist/tui/state/app-state.js +0 -15
- package/dist/tui/state/app-state.js.map +0 -1
- package/dist/tui/state.js +0 -17
- package/dist/tui/state.js.map +0 -1
- package/dist/tui/types.js.map +0 -1
- package/dist/tui/views/add-file-modal.js +0 -129
- package/dist/tui/views/add-file-modal.js.map +0 -1
- package/dist/tui/views/file-preview.js +0 -44
- package/dist/tui/views/file-preview.js.map +0 -1
- package/dist/tui/views/list-packages.js +0 -73
- package/dist/tui/views/list-packages.js.map +0 -1
- package/dist/tui/views/main-menu.js +0 -29
- package/dist/tui/views/main-menu.js.map +0 -1
- package/dist/tui/views/manage-view.js +0 -81
- package/dist/tui/views/manage-view.js.map +0 -1
- package/dist/tui/views/package-hub.js +0 -120
- package/dist/tui/views/package-hub.js.map +0 -1
- package/dist/tui/views/placeholder.js +0 -24
- package/dist/tui/views/placeholder.js.map +0 -1
- package/dist/utils/bun-bootstrap.js +0 -72
- package/dist/utils/bun-bootstrap.js.map +0 -1
- package/dist/utils/entity-id.js +0 -19
- package/dist/utils/entity-id.js.map +0 -1
- package/dist/utils/package-local-files.js +0 -5
- package/dist/utils/package-local-files.js.map +0 -1
- package/dist/utils/path-matching.js +0 -74
- package/dist/utils/path-matching.js.map +0 -1
- package/dist/utils/root-file-operations.js +0 -39
- package/dist/utils/root-file-operations.js.map +0 -1
- package/dist/utils/root-file-transformer.js +0 -27
- package/dist/utils/root-file-transformer.js.map +0 -1
- package/dist/utils/yaml-frontmatter.js +0 -25
- package/dist/utils/yaml-frontmatter.js.map +0 -1
- package/specs/auth/auth-device-flow.md +0 -70
- package/specs/login/login-device-flow.md +0 -70
- package/specs/platforms.md +0 -193
- package/specs/save-pack-versioning.md +0 -224
- package/specs/save-pack.md +0 -68
- /package/dist/{tui → core/source-resolution}/types.js +0 -0
|
@@ -1,25 +1,79 @@
|
|
|
1
1
|
import { dirname, join, relative, parse as parsePath, sep } from 'path';
|
|
2
2
|
import { promises as fs } from 'fs';
|
|
3
|
-
import { exists, ensureDir, listDirectories, listFiles, remove, removeEmptyDirectories, walkFiles } from './fs.js';
|
|
3
|
+
import { exists, ensureDir, listDirectories, listFiles, remove, removeEmptyDirectories, walkFiles, readTextFile } from './fs.js';
|
|
4
4
|
import { writeIfChanged } from '../core/install/file-updater.js';
|
|
5
|
-
import { getLocalPackagesDir } from './paths.js';
|
|
6
5
|
import { packageManager } from '../core/package.js';
|
|
6
|
+
import { getRegistryDirectories } from '../core/directory.js';
|
|
7
7
|
import { logger } from './logger.js';
|
|
8
|
-
import { FILE_PATTERNS,
|
|
8
|
+
import { FILE_PATTERNS, } from '../constants/index.js';
|
|
9
|
+
import { getPlatformRootFileNames, stripRootCopyPrefix } from './platform-root-files.js';
|
|
10
|
+
import { getAllUniversalSubdirs, platformUsesFlows } from '../core/platforms.js';
|
|
9
11
|
import { normalizePathForProcessing } from './path-normalization.js';
|
|
12
|
+
import { formatPathForWorkspaceIndex } from './path-resolution.js';
|
|
10
13
|
import { isAllowedRegistryPath, isRootRegistryPath, isSkippableRegistryPath, normalizeRegistryPath, extractUniversalSubdirInfo } from './registry-entry-filter.js';
|
|
11
14
|
import { mapUniversalToPlatform } from './platform-mapper.js';
|
|
12
15
|
import { safePrompts } from './prompts.js';
|
|
13
|
-
import {
|
|
16
|
+
import { mergeInlinePlatformOverride } from './platform-yaml-merge.js';
|
|
14
17
|
import { parseUniversalPath } from './platform-file.js';
|
|
15
18
|
import { getPlatformDefinition } from '../core/platforms.js';
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
19
|
+
import { sortMapping, ensureTrailingSlash, isDirKey, pruneNestedDirectories } from './package-index-yml.js';
|
|
20
|
+
import { getWorkspaceIndexPath, readWorkspaceIndex, writeWorkspaceIndex } from './workspace-index-yml.js';
|
|
21
|
+
import { resolvePackageContentRoot } from '../core/install/local-source-resolution.js';
|
|
22
|
+
import { calculateFileHash } from './hash-utils.js';
|
|
23
|
+
import { getTargetPath } from './workspace-index-helpers.js';
|
|
24
|
+
async function readPackageIndex(cwd, packageName, _location) {
|
|
25
|
+
const record = await readWorkspaceIndex(cwd);
|
|
26
|
+
const entry = record.index.packages?.[packageName];
|
|
27
|
+
if (!entry)
|
|
28
|
+
return null;
|
|
29
|
+
return {
|
|
30
|
+
path: entry.path ?? '',
|
|
31
|
+
packageName,
|
|
32
|
+
workspace: {
|
|
33
|
+
version: entry.version ?? '',
|
|
34
|
+
hash: undefined
|
|
35
|
+
},
|
|
36
|
+
files: entry.files ?? {}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
async function writePackageIndex(record, cwd) {
|
|
40
|
+
const resolvedCwd = cwd ??
|
|
41
|
+
(record.path
|
|
42
|
+
? dirname(dirname(record.path))
|
|
43
|
+
: undefined);
|
|
44
|
+
if (!resolvedCwd) {
|
|
45
|
+
logger.warn(`Unable to write workspace index for ${record.packageName}: missing cwd`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const wsRecord = await readWorkspaceIndex(resolvedCwd);
|
|
49
|
+
// Be defensive: older/invalid index files could sanitize to missing packages map.
|
|
50
|
+
wsRecord.index.packages = wsRecord.index.packages ?? {};
|
|
51
|
+
const entry = wsRecord.index.packages[record.packageName];
|
|
52
|
+
const rawPath = entry?.path ??
|
|
53
|
+
record.path ??
|
|
54
|
+
(record.workspace?.version
|
|
55
|
+
? join(getRegistryDirectories().packages, record.packageName, record.workspace.version, sep)
|
|
56
|
+
: '');
|
|
57
|
+
if (!rawPath) {
|
|
58
|
+
logger.warn(`Skipping workspace index write for ${record.packageName}: source path is unknown`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// Prefer workspace-relative paths when the source lives under the workspace root.
|
|
62
|
+
// Otherwise, convert absolute paths under ~/.openpackage/ to tilde notation.
|
|
63
|
+
const pathToUse = formatPathForWorkspaceIndex(rawPath, resolvedCwd);
|
|
64
|
+
wsRecord.index.packages[record.packageName] = {
|
|
65
|
+
...entry,
|
|
66
|
+
path: pathToUse,
|
|
67
|
+
version: entry?.version ?? record.workspace?.version,
|
|
68
|
+
files: sortMapping(record.files ?? {})
|
|
69
|
+
};
|
|
70
|
+
await writeWorkspaceIndex(wsRecord);
|
|
71
|
+
}
|
|
18
72
|
// ============================================================================
|
|
19
73
|
// Conflict Planning Functions
|
|
20
74
|
// ============================================================================
|
|
21
75
|
export async function planConflictsForPackage(cwd, packageName, version, platforms) {
|
|
22
|
-
const registryEntries = await loadRegistryFileEntries(packageName, version);
|
|
76
|
+
const registryEntries = await loadRegistryFileEntries(packageName, version, { cwd });
|
|
23
77
|
const plannedFiles = createPlannedFiles(registryEntries);
|
|
24
78
|
attachTargetsToPlannedFiles(cwd, plannedFiles, platforms);
|
|
25
79
|
const otherIndexes = await loadOtherPackageIndexes(cwd, packageName);
|
|
@@ -106,7 +160,62 @@ async function promptConflictResolution(message) {
|
|
|
106
160
|
const choice = response.choice;
|
|
107
161
|
return choice ?? 'skip';
|
|
108
162
|
}
|
|
109
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Prompt user for action when file content differs
|
|
165
|
+
*/
|
|
166
|
+
async function promptContentDifferenceResolution(workspacePath, packagePath) {
|
|
167
|
+
// Format package path as relative to package root with leading slash
|
|
168
|
+
const formattedPackagePath = packagePath
|
|
169
|
+
? (packagePath.startsWith('/') ? packagePath : `/${packagePath}`)
|
|
170
|
+
: undefined;
|
|
171
|
+
const message = formattedPackagePath
|
|
172
|
+
? `Package file ${formattedPackagePath} differs from workspace file ${workspacePath}`
|
|
173
|
+
: `File ${workspacePath} differs from package version`;
|
|
174
|
+
const response = await safePrompts({
|
|
175
|
+
type: 'select',
|
|
176
|
+
name: 'choice',
|
|
177
|
+
message,
|
|
178
|
+
choices: [
|
|
179
|
+
{
|
|
180
|
+
title: 'Overwrite (use package version)',
|
|
181
|
+
value: 'overwrite'
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
title: 'Skip (keep workspace version)',
|
|
185
|
+
value: 'skip'
|
|
186
|
+
}
|
|
187
|
+
]
|
|
188
|
+
});
|
|
189
|
+
const choice = response.choice;
|
|
190
|
+
return choice ?? 'skip';
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Check if file content differs using hash comparison
|
|
194
|
+
*/
|
|
195
|
+
async function hasContentDifference(absPath, newContent) {
|
|
196
|
+
try {
|
|
197
|
+
if (!(await exists(absPath))) {
|
|
198
|
+
return false; // File doesn't exist, so no content difference
|
|
199
|
+
}
|
|
200
|
+
const existingContent = await readTextFile(absPath, 'utf8');
|
|
201
|
+
// Quick check: if content is exactly the same, no need to hash
|
|
202
|
+
if (existingContent === newContent) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
// Hash comparison for definitive answer
|
|
206
|
+
const [existingHash, newHash] = await Promise.all([
|
|
207
|
+
calculateFileHash(existingContent),
|
|
208
|
+
calculateFileHash(newContent)
|
|
209
|
+
]);
|
|
210
|
+
return existingHash !== newHash;
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
logger.warn(`Failed to check content difference for ${absPath}: ${error}`);
|
|
214
|
+
// On error, assume content differs to be safe
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async function updateOwnerIndexAfterRename(owner, oldRelPath, newRelPath, indexByPackage, cwd) {
|
|
110
219
|
const normalizedOld = normalizePathForProcessing(oldRelPath);
|
|
111
220
|
const normalizedNew = normalizePathForProcessing(newRelPath);
|
|
112
221
|
const record = indexByPackage.get(owner.packageName);
|
|
@@ -116,11 +225,21 @@ async function updateOwnerIndexAfterRename(owner, oldRelPath, newRelPath, indexB
|
|
|
116
225
|
const values = record.files[owner.key];
|
|
117
226
|
if (!values)
|
|
118
227
|
return;
|
|
119
|
-
const idx = values.findIndex(
|
|
228
|
+
const idx = values.findIndex(mapping => {
|
|
229
|
+
const target = getTargetPath(mapping);
|
|
230
|
+
return normalizePathForProcessing(target) === normalizedOld;
|
|
231
|
+
});
|
|
120
232
|
if (idx === -1)
|
|
121
233
|
return;
|
|
122
|
-
|
|
123
|
-
|
|
234
|
+
// Update the mapping (preserve keys if it was a complex mapping)
|
|
235
|
+
const oldMapping = values[idx];
|
|
236
|
+
if (typeof oldMapping === 'string') {
|
|
237
|
+
values[idx] = normalizedNew;
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
values[idx] = { ...oldMapping, target: normalizedNew };
|
|
241
|
+
}
|
|
242
|
+
await writePackageIndex(record, cwd);
|
|
124
243
|
}
|
|
125
244
|
else {
|
|
126
245
|
// Directory key still valid; nothing to change.
|
|
@@ -182,7 +301,7 @@ async function resolveConflictsForPlannedFiles(cwd, plannedFiles, context, other
|
|
|
182
301
|
await ensureDir(dirname(absLocalPath));
|
|
183
302
|
try {
|
|
184
303
|
await fs.rename(absTarget, absLocalPath);
|
|
185
|
-
await updateOwnerIndexAfterRename(owner, normalizedRel, localRelPath, indexByPackage);
|
|
304
|
+
await updateOwnerIndexAfterRename(owner, normalizedRel, localRelPath, indexByPackage, cwd);
|
|
186
305
|
context.installedPathOwners.delete(normalizedRel);
|
|
187
306
|
context.installedPathOwners.set(normalizePathForProcessing(localRelPath), owner);
|
|
188
307
|
warnings.push(`Renamed existing ${normalizedRel} from ${owner.packageName} to ${localRelPath}.`);
|
|
@@ -205,23 +324,38 @@ async function resolveConflictsForPlannedFiles(cwd, plannedFiles, context, other
|
|
|
205
324
|
continue;
|
|
206
325
|
}
|
|
207
326
|
if (!previousOwnedPaths.has(normalizedRel) && (await exists(absTarget))) {
|
|
327
|
+
// Check if content actually differs
|
|
328
|
+
const contentDiffers = await hasContentDifference(absTarget, planned.content);
|
|
329
|
+
if (!contentDiffers) {
|
|
330
|
+
// Content is the same, no conflict - just proceed
|
|
331
|
+
filteredTargets.push(target);
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
// Content differs - handle as a conflict
|
|
208
335
|
let decision = perPathDecisions.get(normalizedRel);
|
|
209
336
|
if (!decision) {
|
|
210
337
|
if (options.force) {
|
|
211
|
-
|
|
338
|
+
// Force flag: auto-overwrite (not keep-both)
|
|
339
|
+
decision = 'overwrite';
|
|
340
|
+
warnings.push(`Overwriting ${normalizedRel} (content differs, --force flag active).`);
|
|
212
341
|
}
|
|
213
342
|
else if (defaultStrategy && defaultStrategy !== 'ask') {
|
|
214
343
|
decision = defaultStrategy;
|
|
215
344
|
if (decision === 'skip') {
|
|
216
|
-
warnings.push(`Skipping ${normalizedRel}
|
|
345
|
+
warnings.push(`Skipping ${normalizedRel} (content differs, configured conflict strategy).`);
|
|
346
|
+
}
|
|
347
|
+
else if (decision === 'overwrite') {
|
|
348
|
+
warnings.push(`Overwriting ${normalizedRel} (content differs, configured conflict strategy).`);
|
|
217
349
|
}
|
|
218
350
|
}
|
|
219
351
|
else if (!interactive) {
|
|
220
|
-
warnings.push(`Skipping ${normalizedRel}
|
|
352
|
+
warnings.push(`Skipping ${normalizedRel} (content differs, cannot prompt in non-interactive mode).`);
|
|
221
353
|
decision = 'skip';
|
|
222
354
|
}
|
|
223
355
|
else {
|
|
224
|
-
|
|
356
|
+
// Interactive mode: prompt for content-modified files
|
|
357
|
+
const contentDecision = await promptContentDifferenceResolution(normalizedRel, planned.registryPath);
|
|
358
|
+
decision = contentDecision;
|
|
225
359
|
}
|
|
226
360
|
}
|
|
227
361
|
if (decision === 'skip') {
|
|
@@ -249,7 +383,7 @@ async function resolveConflictsForPlannedFiles(cwd, plannedFiles, context, other
|
|
|
249
383
|
}
|
|
250
384
|
// overwrite
|
|
251
385
|
if (isDryRun) {
|
|
252
|
-
warnings.push(`Would overwrite existing local file ${normalizedRel}.`);
|
|
386
|
+
warnings.push(`Would overwrite existing local file ${normalizedRel} (content modified).`);
|
|
253
387
|
filteredTargets.push(target);
|
|
254
388
|
continue;
|
|
255
389
|
}
|
|
@@ -270,52 +404,25 @@ function normalizeRelativePath(cwd, absPath) {
|
|
|
270
404
|
const normalized = normalizePathForProcessing(rel);
|
|
271
405
|
return normalized.replace(/\\/g, '/');
|
|
272
406
|
}
|
|
273
|
-
async function collectPackageDirectories(cwd) {
|
|
274
|
-
const packagesRoot = getLocalPackagesDir(cwd);
|
|
275
|
-
if (!(await exists(packagesRoot))) {
|
|
276
|
-
return [];
|
|
277
|
-
}
|
|
278
|
-
const results = [];
|
|
279
|
-
async function recurse(currentDir, relativeBase) {
|
|
280
|
-
const packageYmlPath = join(currentDir, FILE_PATTERNS.PACKAGE_YML);
|
|
281
|
-
if (await exists(packageYmlPath)) {
|
|
282
|
-
const packageName = relativeBase.replace(new RegExp(`\\${sep}`, 'g'), '/');
|
|
283
|
-
results.push({ packageName, dir: currentDir });
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
const subdirs = await listDirectories(currentDir).catch(() => []);
|
|
287
|
-
for (const subdir of subdirs) {
|
|
288
|
-
const nextDir = join(currentDir, subdir);
|
|
289
|
-
const nextRelative = relativeBase ? `${relativeBase}${sep}${subdir}` : subdir;
|
|
290
|
-
await recurse(nextDir, nextRelative);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
const topLevelDirs = await listDirectories(packagesRoot).catch(() => []);
|
|
294
|
-
for (const dir of topLevelDirs) {
|
|
295
|
-
const absolute = join(packagesRoot, dir);
|
|
296
|
-
await recurse(absolute, dir);
|
|
297
|
-
}
|
|
298
|
-
return results;
|
|
299
|
-
}
|
|
300
407
|
export async function loadOtherPackageIndexes(cwd, excludePackage) {
|
|
301
|
-
const
|
|
408
|
+
const record = await readWorkspaceIndex(cwd);
|
|
409
|
+
const wsPath = getWorkspaceIndexPath(cwd);
|
|
410
|
+
const packages = record.index.packages ?? {};
|
|
302
411
|
const results = [];
|
|
303
|
-
for (const entry of
|
|
304
|
-
if (
|
|
305
|
-
continue;
|
|
306
|
-
const indexPath = join(entry.dir, FILE_PATTERNS.PACKAGE_INDEX_YML);
|
|
307
|
-
if (!(await exists(indexPath)))
|
|
412
|
+
for (const [name, entry] of Object.entries(packages)) {
|
|
413
|
+
if (name === excludePackage)
|
|
308
414
|
continue;
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
415
|
+
results.push({
|
|
416
|
+
path: entry?.path ?? wsPath,
|
|
417
|
+
packageName: name,
|
|
418
|
+
workspace: { version: entry?.version ?? '' },
|
|
419
|
+
files: entry?.files ?? {}
|
|
420
|
+
});
|
|
314
421
|
}
|
|
315
422
|
return results;
|
|
316
423
|
}
|
|
317
|
-
async function collectFilesUnderDirectory(cwd,
|
|
318
|
-
const directoryRel = ensureTrailingSlash(normalizePathForProcessing(
|
|
424
|
+
async function collectFilesUnderDirectory(cwd, dirRelPath) {
|
|
425
|
+
const directoryRel = ensureTrailingSlash(normalizePathForProcessing(dirRelPath));
|
|
319
426
|
const absDir = join(cwd, directoryRel);
|
|
320
427
|
if (!(await exists(absDir))) {
|
|
321
428
|
return [];
|
|
@@ -341,15 +448,15 @@ async function buildExpandedIndexesContext(cwd, indexes) {
|
|
|
341
448
|
const owner = {
|
|
342
449
|
packageName: record.packageName,
|
|
343
450
|
key,
|
|
344
|
-
type: key.endsWith('/') ? 'dir' : 'file'
|
|
345
|
-
indexPath: record.path
|
|
451
|
+
type: key.endsWith('/') ? 'dir' : 'file'
|
|
346
452
|
};
|
|
347
453
|
if (owner.type === 'dir') {
|
|
348
454
|
if (!dirKeyOwners.has(key)) {
|
|
349
455
|
dirKeyOwners.set(key, []);
|
|
350
456
|
}
|
|
351
457
|
dirKeyOwners.get(key).push(owner);
|
|
352
|
-
for (const
|
|
458
|
+
for (const mapping of values) {
|
|
459
|
+
const dirRel = getTargetPath(mapping);
|
|
353
460
|
const files = await collectFilesUnderDirectory(cwd, dirRel);
|
|
354
461
|
for (const filePath of files) {
|
|
355
462
|
if (!installedPathOwners.has(filePath)) {
|
|
@@ -359,7 +466,8 @@ async function buildExpandedIndexesContext(cwd, indexes) {
|
|
|
359
466
|
}
|
|
360
467
|
}
|
|
361
468
|
else {
|
|
362
|
-
for (const
|
|
469
|
+
for (const mapping of values) {
|
|
470
|
+
const fileRel = getTargetPath(mapping);
|
|
363
471
|
const normalizedValue = normalizePathForProcessing(fileRel);
|
|
364
472
|
if (!installedPathOwners.has(normalizedValue)) {
|
|
365
473
|
installedPathOwners.set(normalizedValue, owner);
|
|
@@ -373,8 +481,15 @@ async function buildExpandedIndexesContext(cwd, indexes) {
|
|
|
373
481
|
// ============================================================================
|
|
374
482
|
// Registry File Loading Functions
|
|
375
483
|
// ============================================================================
|
|
376
|
-
async function loadRegistryFileEntries(packageName, version) {
|
|
377
|
-
const
|
|
484
|
+
async function loadRegistryFileEntries(packageName, version, opts) {
|
|
485
|
+
const packageRootDir = opts?.contentRoot && (await exists(opts.contentRoot))
|
|
486
|
+
? opts.contentRoot
|
|
487
|
+
: opts?.cwd
|
|
488
|
+
? await resolvePackageContentRoot({ cwd: opts.cwd, packageName, version })
|
|
489
|
+
: undefined;
|
|
490
|
+
const pkg = await packageManager.loadPackage(packageName, version, {
|
|
491
|
+
packageRootDir
|
|
492
|
+
});
|
|
378
493
|
const entries = [];
|
|
379
494
|
for (const file of pkg.files) {
|
|
380
495
|
const normalized = normalizeRegistryPath(file.path);
|
|
@@ -382,7 +497,7 @@ async function loadRegistryFileEntries(packageName, version) {
|
|
|
382
497
|
if (isRootRegistryPath(normalized)) {
|
|
383
498
|
continue;
|
|
384
499
|
}
|
|
385
|
-
if (!isAllowedRegistryPath(normalized)) {
|
|
500
|
+
if (!isAllowedRegistryPath(normalized, opts?.cwd)) {
|
|
386
501
|
// Ignore any other top-level paths (e.g., README.md, some/...)
|
|
387
502
|
continue;
|
|
388
503
|
}
|
|
@@ -394,15 +509,15 @@ async function loadRegistryFileEntries(packageName, version) {
|
|
|
394
509
|
}
|
|
395
510
|
return entries;
|
|
396
511
|
}
|
|
397
|
-
function deriveGroupKey(registryPath) {
|
|
512
|
+
function deriveGroupKey(registryPath, cwd) {
|
|
398
513
|
const normalized = normalizeRegistryPath(registryPath);
|
|
399
514
|
const segments = normalized.split('/');
|
|
400
515
|
if (segments.length <= 1) {
|
|
401
516
|
return '';
|
|
402
517
|
}
|
|
403
518
|
const first = segments[0];
|
|
404
|
-
const
|
|
405
|
-
if (
|
|
519
|
+
const universalSubdirs = getAllUniversalSubdirs(cwd);
|
|
520
|
+
if (universalSubdirs.has(first)) {
|
|
406
521
|
if (segments.length >= 2) {
|
|
407
522
|
return ensureTrailingSlash(`${segments[0]}/${segments[1]}`);
|
|
408
523
|
}
|
|
@@ -421,10 +536,10 @@ function createPlannedFiles(entries) {
|
|
|
421
536
|
targets: []
|
|
422
537
|
}));
|
|
423
538
|
}
|
|
424
|
-
function groupPlannedFiles(plannedFiles) {
|
|
539
|
+
function groupPlannedFiles(plannedFiles, cwd) {
|
|
425
540
|
const groups = new Map();
|
|
426
541
|
for (const planned of plannedFiles) {
|
|
427
|
-
const key = deriveGroupKey(planned.registryPath);
|
|
542
|
+
const key = deriveGroupKey(planned.registryPath, cwd);
|
|
428
543
|
if (!groups.has(key)) {
|
|
429
544
|
groups.set(key, []);
|
|
430
545
|
}
|
|
@@ -435,7 +550,7 @@ function groupPlannedFiles(plannedFiles) {
|
|
|
435
550
|
// ============================================================================
|
|
436
551
|
// Planning Functions
|
|
437
552
|
// ============================================================================
|
|
438
|
-
function buildPlannedTargetMap(plannedFiles,
|
|
553
|
+
function buildPlannedTargetMap(plannedFiles, cwd) {
|
|
439
554
|
const map = new Map();
|
|
440
555
|
const universalPlanned = [];
|
|
441
556
|
const platformSuffixedPlanned = [];
|
|
@@ -452,16 +567,17 @@ function buildPlannedTargetMap(plannedFiles, yamlOverrides) {
|
|
|
452
567
|
for (const { planned, parsed } of entries) {
|
|
453
568
|
for (const target of planned.targets) {
|
|
454
569
|
const normalizedRel = normalizePathForProcessing(target.relPath);
|
|
455
|
-
// Compute per-target content (apply platform
|
|
570
|
+
// Compute per-target content (apply inline platform overrides for universal files)
|
|
456
571
|
let content = planned.content;
|
|
457
|
-
if (parsed && target.platform && target.platform !== 'other') {
|
|
458
|
-
content =
|
|
572
|
+
if (parsed && !parsed.platformSuffix && target.platform && target.platform !== 'other') {
|
|
573
|
+
content = mergeInlinePlatformOverride(planned.content, target.platform, cwd);
|
|
459
574
|
}
|
|
460
575
|
map.set(normalizedRel, {
|
|
461
576
|
absPath: target.absPath,
|
|
462
577
|
relPath: normalizedRel,
|
|
463
578
|
content,
|
|
464
|
-
encoding: planned.encoding
|
|
579
|
+
encoding: planned.encoding,
|
|
580
|
+
sourcePath: planned.registryPath
|
|
465
581
|
});
|
|
466
582
|
}
|
|
467
583
|
}
|
|
@@ -480,7 +596,7 @@ function computeDiff(plannedMap, previousOwnedPaths) {
|
|
|
480
596
|
}
|
|
481
597
|
return { planned: plannedMap, deletions };
|
|
482
598
|
}
|
|
483
|
-
async function applyFileOperations(cwd, planned, deletions, options) {
|
|
599
|
+
async function applyFileOperations(cwd, planned, deletions, options, packageName, contentRoot) {
|
|
484
600
|
const result = {
|
|
485
601
|
installed: 0,
|
|
486
602
|
updated: 0,
|
|
@@ -512,6 +628,53 @@ async function applyFileOperations(cwd, planned, deletions, options) {
|
|
|
512
628
|
}
|
|
513
629
|
for (const [rel, detail] of planned.entries()) {
|
|
514
630
|
const absPath = detail.absPath;
|
|
631
|
+
// Check for content differences before writing
|
|
632
|
+
if (await exists(absPath)) {
|
|
633
|
+
const contentDiffers = await hasContentDifference(absPath, detail.content);
|
|
634
|
+
if (contentDiffers) {
|
|
635
|
+
// Content differs - need to handle conflict
|
|
636
|
+
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
637
|
+
let shouldWrite = false;
|
|
638
|
+
if (isDryRun) {
|
|
639
|
+
logger.warn(`Would overwrite ${rel} (content differs from package)`);
|
|
640
|
+
result.skipped++;
|
|
641
|
+
continue;
|
|
642
|
+
}
|
|
643
|
+
if (options.force) {
|
|
644
|
+
logger.warn(`Overwriting ${rel} (content differs, --force flag active)`);
|
|
645
|
+
shouldWrite = true;
|
|
646
|
+
}
|
|
647
|
+
else if (options.conflictStrategy === 'overwrite') {
|
|
648
|
+
logger.warn(`Overwriting ${rel} (content differs, configured conflict strategy)`);
|
|
649
|
+
shouldWrite = true;
|
|
650
|
+
}
|
|
651
|
+
else if (options.conflictStrategy === 'skip') {
|
|
652
|
+
logger.warn(`Skipping ${rel} (content differs, configured conflict strategy)`);
|
|
653
|
+
result.skipped++;
|
|
654
|
+
continue;
|
|
655
|
+
}
|
|
656
|
+
else if (!interactive) {
|
|
657
|
+
logger.warn(`Skipping ${rel} (content differs, cannot prompt in non-interactive mode)`);
|
|
658
|
+
result.skipped++;
|
|
659
|
+
continue;
|
|
660
|
+
}
|
|
661
|
+
else {
|
|
662
|
+
// Interactive mode: prompt user
|
|
663
|
+
// Use registry path (relative to package root)
|
|
664
|
+
const decision = await promptContentDifferenceResolution(rel, detail.sourcePath);
|
|
665
|
+
if (decision === 'skip') {
|
|
666
|
+
logger.info(`Skipped ${rel} (keeping workspace version)`);
|
|
667
|
+
result.skipped++;
|
|
668
|
+
continue;
|
|
669
|
+
}
|
|
670
|
+
shouldWrite = true;
|
|
671
|
+
}
|
|
672
|
+
if (!shouldWrite) {
|
|
673
|
+
result.skipped++;
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
515
678
|
if (isDryRun) {
|
|
516
679
|
result.skipped++;
|
|
517
680
|
continue;
|
|
@@ -637,63 +800,42 @@ function buildIndexMappingFromPlans(plans) {
|
|
|
637
800
|
// ============================================================================
|
|
638
801
|
// Main Install Function
|
|
639
802
|
// ============================================================================
|
|
640
|
-
export async function installPackageByIndex(cwd, packageName, version, platforms, options, includePaths) {
|
|
641
|
-
|
|
642
|
-
const
|
|
643
|
-
|
|
644
|
-
:
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
const context = await buildExpandedIndexesContext(cwd, otherIndexes);
|
|
671
|
-
const groupPlans = await decideGroupPlans(cwd, groups, previousIndex, context);
|
|
672
|
-
const previousOwnedPaths = await expandIndexToFilePaths(cwd, previousIndex);
|
|
673
|
-
const conflictWarnings = await resolveConflictsForPlannedFiles(cwd, plannedFiles, context, otherIndexes, previousOwnedPaths, options);
|
|
674
|
-
for (const warning of conflictWarnings) {
|
|
675
|
-
logger.warn(warning);
|
|
676
|
-
}
|
|
677
|
-
// Load platform YAML overrides once per install
|
|
678
|
-
const yamlOverrides = await loadRegistryYamlOverrides(packageName, version);
|
|
679
|
-
const plannedTargetMap = buildPlannedTargetMap(plannedFiles, yamlOverrides);
|
|
680
|
-
const { planned, deletions } = computeDiff(plannedTargetMap, previousOwnedPaths);
|
|
681
|
-
const operationResult = await applyFileOperations(cwd, planned, deletions, options);
|
|
682
|
-
if (!options.dryRun) {
|
|
683
|
-
const mapping = buildIndexMappingFromPlans(groupPlans);
|
|
684
|
-
const workspaceHash = previousIndex?.workspace?.hash ?? createWorkspaceHash(cwd);
|
|
685
|
-
const indexRecord = {
|
|
686
|
-
path: getPackageIndexPath(cwd, packageName),
|
|
687
|
-
packageName,
|
|
688
|
-
workspace: {
|
|
689
|
-
hash: workspaceHash,
|
|
690
|
-
version
|
|
691
|
-
},
|
|
692
|
-
files: mapping
|
|
693
|
-
};
|
|
694
|
-
await writePackageIndex(indexRecord);
|
|
803
|
+
export async function installPackageByIndex(cwd, packageName, version, platforms, options, includePaths, contentRoot) {
|
|
804
|
+
// Check if any platform uses flows
|
|
805
|
+
const hasFlowPlatforms = platforms.some(platform => platformUsesFlows(platform, cwd));
|
|
806
|
+
if (hasFlowPlatforms) {
|
|
807
|
+
logger.debug(`Using flow-based installer for ${packageName} on platforms: ${platforms.join(', ')}`);
|
|
808
|
+
// Load package to get format metadata (important for plugin conversion)
|
|
809
|
+
let packageFormat = undefined;
|
|
810
|
+
if (contentRoot) {
|
|
811
|
+
try {
|
|
812
|
+
const { loadPackageFromPath } = await import('../core/install/path-package-loader.js');
|
|
813
|
+
const pkg = await loadPackageFromPath(contentRoot);
|
|
814
|
+
// Extract format metadata if available (set by plugin transformer)
|
|
815
|
+
if (pkg._format) {
|
|
816
|
+
packageFormat = pkg._format;
|
|
817
|
+
logger.debug(`Package format detected from _format field`, {
|
|
818
|
+
type: packageFormat.type,
|
|
819
|
+
platform: packageFormat.platform
|
|
820
|
+
});
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
catch (error) {
|
|
824
|
+
// If we can't load the package for format detection, that's OK
|
|
825
|
+
// Format will be detected from files instead
|
|
826
|
+
logger.debug(`Could not load package for format detection: ${error.message}`);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
// Delegate to flow-based installer
|
|
830
|
+
const { installPackageByIndexWithFlows } = await import('./flow-index-installer.js');
|
|
831
|
+
return await installPackageByIndexWithFlows(cwd, packageName, version, platforms, options, includePaths, contentRoot, packageFormat // Pass format metadata
|
|
832
|
+
);
|
|
695
833
|
}
|
|
696
|
-
|
|
834
|
+
// No platforms use flows - this should not happen with current config
|
|
835
|
+
throw new Error(`Platform(s) ${platforms.join(', ')} do not use flows. ` +
|
|
836
|
+
`Flow-based installation is required. Please check platforms.jsonc configuration.`);
|
|
837
|
+
// Legacy subdirs-based code removed - now using flow-based installation exclusively
|
|
838
|
+
// See flow-index-installer.ts for the new implementation
|
|
697
839
|
}
|
|
698
840
|
// ============================================================================
|
|
699
841
|
// Target Mapping Functions
|
|
@@ -704,7 +846,8 @@ async function expandIndexToFilePaths(cwd, index) {
|
|
|
704
846
|
return owned;
|
|
705
847
|
for (const [key, values] of Object.entries(index.files)) {
|
|
706
848
|
if (isDirKey(key)) {
|
|
707
|
-
for (const
|
|
849
|
+
for (const mapping of values) {
|
|
850
|
+
const dirRel = getTargetPath(mapping);
|
|
708
851
|
const files = await collectFilesUnderDirectory(cwd, dirRel);
|
|
709
852
|
for (const rel of files) {
|
|
710
853
|
owned.add(normalizePathForProcessing(rel));
|
|
@@ -712,7 +855,8 @@ async function expandIndexToFilePaths(cwd, index) {
|
|
|
712
855
|
}
|
|
713
856
|
}
|
|
714
857
|
else {
|
|
715
|
-
for (const
|
|
858
|
+
for (const mapping of values) {
|
|
859
|
+
const value = getTargetPath(mapping);
|
|
716
860
|
owned.add(normalizePathForProcessing(value));
|
|
717
861
|
}
|
|
718
862
|
}
|
|
@@ -722,7 +866,7 @@ async function expandIndexToFilePaths(cwd, index) {
|
|
|
722
866
|
function mapRegistryPathToTargets(cwd, registryPath, platforms) {
|
|
723
867
|
const normalized = normalizeRegistryPath(registryPath);
|
|
724
868
|
const targets = [];
|
|
725
|
-
const universalInfo = extractUniversalSubdirInfo(normalized);
|
|
869
|
+
const universalInfo = extractUniversalSubdirInfo(normalized, cwd);
|
|
726
870
|
if (universalInfo) {
|
|
727
871
|
// Parse the universal path to detect platform suffix and normalized relative path
|
|
728
872
|
const parsed = parseUniversalPath(normalized);
|
|
@@ -731,8 +875,8 @@ function mapRegistryPathToTargets(cwd, registryPath, platforms) {
|
|
|
731
875
|
const targetPlatform = parsed.platformSuffix;
|
|
732
876
|
if (platforms.includes(targetPlatform)) {
|
|
733
877
|
try {
|
|
734
|
-
const mapped = mapUniversalToPlatform(targetPlatform, parsed.universalSubdir, parsed.relPath);
|
|
735
|
-
const targetAbs = join(cwd, mapped.
|
|
878
|
+
const mapped = mapUniversalToPlatform(targetPlatform, parsed.universalSubdir, parsed.relPath, cwd);
|
|
879
|
+
const targetAbs = join(cwd, mapped.relFile);
|
|
736
880
|
targets.push({
|
|
737
881
|
absPath: targetAbs,
|
|
738
882
|
relPath: normalizeRelativePath(cwd, targetAbs),
|
|
@@ -749,8 +893,8 @@ function mapRegistryPathToTargets(cwd, registryPath, platforms) {
|
|
|
749
893
|
const rel = parsed ? parsed.relPath : universalInfo.relPath;
|
|
750
894
|
for (const platform of platforms) {
|
|
751
895
|
try {
|
|
752
|
-
const mapped = mapUniversalToPlatform(platform, universalInfo.universalSubdir, rel);
|
|
753
|
-
const targetAbs = join(cwd, mapped.
|
|
896
|
+
const mapped = mapUniversalToPlatform(platform, universalInfo.universalSubdir, rel, cwd);
|
|
897
|
+
const targetAbs = join(cwd, mapped.relFile);
|
|
754
898
|
targets.push({
|
|
755
899
|
absPath: targetAbs,
|
|
756
900
|
relPath: normalizeRelativePath(cwd, targetAbs),
|
|
@@ -865,7 +1009,8 @@ function hadPreviousDirForPlatform(previousIndex, groupKey, platform) {
|
|
|
865
1009
|
return false;
|
|
866
1010
|
}
|
|
867
1011
|
const rootDir = normalizePathForProcessing(getPlatformDefinition(platform).rootDir);
|
|
868
|
-
for (const
|
|
1012
|
+
for (const mapping of prevValues) {
|
|
1013
|
+
const value = getTargetPath(mapping);
|
|
869
1014
|
const normalizedValue = normalizePathForProcessing(value);
|
|
870
1015
|
if (normalizedValue === rootDir ||
|
|
871
1016
|
normalizedValue.startsWith(`${rootDir}/`)) {
|
|
@@ -924,6 +1069,62 @@ async function decideGroupPlans(cwd, groups, previousIndex, context) {
|
|
|
924
1069
|
// ============================================================================
|
|
925
1070
|
// Shared Helper for Building Index Mappings
|
|
926
1071
|
// ============================================================================
|
|
1072
|
+
function addMappingValue(mapping, key, value) {
|
|
1073
|
+
if (!mapping[key]) {
|
|
1074
|
+
mapping[key] = [];
|
|
1075
|
+
}
|
|
1076
|
+
if (!mapping[key].includes(value)) {
|
|
1077
|
+
mapping[key].push(value);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
async function augmentIndexMappingWithRootAndCopyToRoot(cwd, mapping, packageFiles, platforms) {
|
|
1081
|
+
const augmented = { ...mapping };
|
|
1082
|
+
const rootFileNames = getPlatformRootFileNames(platforms);
|
|
1083
|
+
const explicitRootKeys = new Set();
|
|
1084
|
+
const hasAgents = packageFiles.some(file => normalizeRegistryPath(file.path) === FILE_PATTERNS.AGENTS_MD);
|
|
1085
|
+
for (const file of packageFiles) {
|
|
1086
|
+
const normalized = normalizeRegistryPath(file.path);
|
|
1087
|
+
const stripped = stripRootCopyPrefix(normalized);
|
|
1088
|
+
if (stripped !== null) {
|
|
1089
|
+
if (await exists(join(cwd, stripped))) {
|
|
1090
|
+
addMappingValue(augmented, normalized, stripped);
|
|
1091
|
+
}
|
|
1092
|
+
continue;
|
|
1093
|
+
}
|
|
1094
|
+
if (rootFileNames.has(normalized) || isRootRegistryPath(normalized)) {
|
|
1095
|
+
explicitRootKeys.add(normalized);
|
|
1096
|
+
if (await exists(join(cwd, normalized))) {
|
|
1097
|
+
addMappingValue(augmented, normalized, normalized);
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
// For allowed registry paths, if the file already exists at the workspace-relative path,
|
|
1102
|
+
// record that concrete location. This is important for root packages and for "add"/"save"
|
|
1103
|
+
// flows where the source path itself is the only existing workspace location before apply/install.
|
|
1104
|
+
for (const file of packageFiles) {
|
|
1105
|
+
const normalized = normalizeRegistryPath(file.path);
|
|
1106
|
+
if (!isAllowedRegistryPath(normalized, cwd))
|
|
1107
|
+
continue;
|
|
1108
|
+
if (isSkippableRegistryPath(normalized, cwd))
|
|
1109
|
+
continue;
|
|
1110
|
+
if (await exists(join(cwd, normalized))) {
|
|
1111
|
+
addMappingValue(augmented, normalized, normalized);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
// AGENTS.md can populate platform root files when no explicit override exists in the package.
|
|
1115
|
+
if (hasAgents) {
|
|
1116
|
+
for (const rootFile of rootFileNames) {
|
|
1117
|
+
if (rootFile === FILE_PATTERNS.AGENTS_MD)
|
|
1118
|
+
continue;
|
|
1119
|
+
if (explicitRootKeys.has(rootFile))
|
|
1120
|
+
continue;
|
|
1121
|
+
if (await exists(join(cwd, rootFile))) {
|
|
1122
|
+
addMappingValue(augmented, FILE_PATTERNS.AGENTS_MD, rootFile);
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
return sortMapping(augmented);
|
|
1127
|
+
}
|
|
927
1128
|
/**
|
|
928
1129
|
* Build index mapping for package files using the same logic flow as installPackageByIndex
|
|
929
1130
|
* This function reuses the planning, grouping, and decision logic to ensure consistency
|
|
@@ -944,9 +1145,9 @@ export async function buildIndexMappingForPackageFiles(cwd, packageFiles, platfo
|
|
|
944
1145
|
// Skip root files and skippable paths (same logic as loadRegistryFileEntries)
|
|
945
1146
|
if (isRootRegistryPath(normalized))
|
|
946
1147
|
return false;
|
|
947
|
-
if (isSkippableRegistryPath(normalized))
|
|
1148
|
+
if (isSkippableRegistryPath(normalized, cwd))
|
|
948
1149
|
return false;
|
|
949
|
-
return isAllowedRegistryPath(normalized);
|
|
1150
|
+
return isAllowedRegistryPath(normalized, cwd);
|
|
950
1151
|
})
|
|
951
1152
|
.map(file => ({
|
|
952
1153
|
registryPath: normalizeRegistryPath(file.path),
|
|
@@ -954,26 +1155,27 @@ export async function buildIndexMappingForPackageFiles(cwd, packageFiles, platfo
|
|
|
954
1155
|
encoding: file.encoding
|
|
955
1156
|
}));
|
|
956
1157
|
if (registryEntries.length === 0) {
|
|
957
|
-
return {};
|
|
1158
|
+
return await augmentIndexMappingWithRootAndCopyToRoot(cwd, {}, packageFiles, platforms);
|
|
958
1159
|
}
|
|
959
1160
|
// Reuse existing planning logic - this ensures consistency with installPackageByIndex
|
|
960
1161
|
const plannedFiles = createPlannedFiles(registryEntries);
|
|
961
1162
|
attachTargetsToPlannedFiles(cwd, plannedFiles, platforms);
|
|
962
|
-
const groups = groupPlannedFiles(plannedFiles);
|
|
1163
|
+
const groups = groupPlannedFiles(plannedFiles, cwd);
|
|
963
1164
|
const context = await buildExpandedIndexesContext(cwd, otherIndexes);
|
|
964
1165
|
const groupPlans = await decideGroupPlans(cwd, groups, previousIndex, context);
|
|
965
1166
|
// Build the mapping using the same logic as installPackageByIndex
|
|
966
|
-
|
|
1167
|
+
const mapping = buildIndexMappingFromPlans(groupPlans);
|
|
1168
|
+
return await augmentIndexMappingWithRootAndCopyToRoot(cwd, mapping, packageFiles, platforms);
|
|
967
1169
|
}
|
|
968
|
-
function filterRegistryEntriesForPackageFiles(packageFiles) {
|
|
1170
|
+
function filterRegistryEntriesForPackageFiles(packageFiles, cwd) {
|
|
969
1171
|
return packageFiles
|
|
970
1172
|
.filter(file => {
|
|
971
1173
|
const normalized = normalizeRegistryPath(file.path);
|
|
972
1174
|
if (isRootRegistryPath(normalized))
|
|
973
1175
|
return false;
|
|
974
|
-
if (isSkippableRegistryPath(normalized))
|
|
1176
|
+
if (isSkippableRegistryPath(normalized, cwd))
|
|
975
1177
|
return false;
|
|
976
|
-
return isAllowedRegistryPath(normalized);
|
|
1178
|
+
return isAllowedRegistryPath(normalized, cwd);
|
|
977
1179
|
})
|
|
978
1180
|
.map(file => ({
|
|
979
1181
|
registryPath: normalizeRegistryPath(file.path),
|
|
@@ -982,36 +1184,27 @@ function filterRegistryEntriesForPackageFiles(packageFiles) {
|
|
|
982
1184
|
}));
|
|
983
1185
|
}
|
|
984
1186
|
export async function applyPlannedSyncForPackageFiles(cwd, packageName, version, packageFiles, platforms, options, location = 'nested') {
|
|
985
|
-
const registryEntries = filterRegistryEntriesForPackageFiles(packageFiles);
|
|
1187
|
+
const registryEntries = filterRegistryEntriesForPackageFiles(packageFiles, cwd);
|
|
986
1188
|
const plannedFiles = createPlannedFiles(registryEntries);
|
|
987
1189
|
attachTargetsToPlannedFiles(cwd, plannedFiles, platforms);
|
|
988
1190
|
const previousIndex = await readPackageIndex(cwd, packageName, location);
|
|
989
1191
|
const otherIndexes = await loadOtherPackageIndexes(cwd, packageName);
|
|
990
1192
|
const context = await buildExpandedIndexesContext(cwd, otherIndexes);
|
|
991
|
-
const groups = groupPlannedFiles(plannedFiles);
|
|
1193
|
+
const groups = groupPlannedFiles(plannedFiles, cwd);
|
|
992
1194
|
const groupPlans = await decideGroupPlans(cwd, groups, previousIndex, context);
|
|
993
1195
|
const previousOwnedPaths = await expandIndexToFilePaths(cwd, previousIndex);
|
|
994
1196
|
const conflictWarnings = await resolveConflictsForPlannedFiles(cwd, plannedFiles, context, otherIndexes, previousOwnedPaths, options);
|
|
995
1197
|
for (const warning of conflictWarnings) {
|
|
996
1198
|
logger.warn(warning);
|
|
997
1199
|
}
|
|
998
|
-
const plannedTargetMap = buildPlannedTargetMap(plannedFiles,
|
|
1200
|
+
const plannedTargetMap = buildPlannedTargetMap(plannedFiles, cwd);
|
|
999
1201
|
const { planned, deletions } = computeDiff(plannedTargetMap, previousOwnedPaths);
|
|
1000
|
-
|
|
1202
|
+
// Try to get contentRoot from previous index for better messaging
|
|
1203
|
+
const contentRoot = previousIndex?.path;
|
|
1204
|
+
const operationResult = await applyFileOperations(cwd, planned, deletions, options, packageName, contentRoot);
|
|
1001
1205
|
let mapping = {};
|
|
1002
1206
|
if (!options.dryRun) {
|
|
1003
|
-
mapping = buildIndexMappingFromPlans(groupPlans);
|
|
1004
|
-
const workspaceHash = previousIndex?.workspace?.hash ?? createWorkspaceHash(cwd);
|
|
1005
|
-
const indexRecord = {
|
|
1006
|
-
path: getPackageIndexPath(cwd, packageName, location),
|
|
1007
|
-
packageName,
|
|
1008
|
-
workspace: {
|
|
1009
|
-
hash: workspaceHash,
|
|
1010
|
-
version
|
|
1011
|
-
},
|
|
1012
|
-
files: mapping
|
|
1013
|
-
};
|
|
1014
|
-
await writePackageIndex(indexRecord);
|
|
1207
|
+
mapping = await augmentIndexMappingWithRootAndCopyToRoot(cwd, buildIndexMappingFromPlans(groupPlans), packageFiles, platforms);
|
|
1015
1208
|
}
|
|
1016
1209
|
return {
|
|
1017
1210
|
operation: operationResult,
|