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
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
# Universal Platform Converter
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The **Universal Platform Converter** enables OpenPackage to install platform-specific packages (like Claude Code plugins) across different platforms by automatically converting between formats.
|
|
6
|
+
|
|
7
|
+
**Key capability:** Install a Claude Code plugin directly into Cursor, OpenCode, or any other platform without manual conversion.
|
|
8
|
+
|
|
9
|
+
## Problem Statement
|
|
10
|
+
|
|
11
|
+
Previously, OpenPackage expected all packages to be in **universal format** (with `commands/`, `agents/`, `rules/` subdirectories). Platform-specific packages like Claude Code plugins use a different structure (`.claude/commands/`, `.claude/agents/`, etc.).
|
|
12
|
+
|
|
13
|
+
**The challenge:**
|
|
14
|
+
- Claude Code plugins are already in Claude format
|
|
15
|
+
- Installing to Claude platform: Should copy files AS-IS (no transformation)
|
|
16
|
+
- Installing to other platforms: Need to convert Claude → Universal → Target Platform
|
|
17
|
+
|
|
18
|
+
## Solution Architecture
|
|
19
|
+
|
|
20
|
+
### Three-Phase Approach
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
┌─────────────────────────────────────────────────────────┐
|
|
24
|
+
│ Phase 1: Format Detection │
|
|
25
|
+
│ - Analyze package file structure │
|
|
26
|
+
│ - Determine: universal or platform-specific │
|
|
27
|
+
│ - Calculate confidence score │
|
|
28
|
+
└─────────────────────────────────────────────────────────┘
|
|
29
|
+
↓
|
|
30
|
+
┌─────────────────────────────────────────────────────────┐
|
|
31
|
+
│ Phase 2: Strategy Selection │
|
|
32
|
+
│ • Source = Target Platform → Install AS-IS │
|
|
33
|
+
│ • Source ≠ Target Platform → Convert │
|
|
34
|
+
│ • Universal Format → Standard Flow Installation │
|
|
35
|
+
└─────────────────────────────────────────────────────────┘
|
|
36
|
+
↓
|
|
37
|
+
┌─────────────────────────────────────────────────────────┐
|
|
38
|
+
│ Phase 3: Execution │
|
|
39
|
+
│ - Direct copy (AS-IS) │
|
|
40
|
+
│ - OR: Bidirectional flow conversion │
|
|
41
|
+
│ - OR: Standard flow-based installation │
|
|
42
|
+
└─────────────────────────────────────────────────────────┘
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Core Components
|
|
46
|
+
|
|
47
|
+
### 1. Format Detector (`format-detector.ts`)
|
|
48
|
+
|
|
49
|
+
**Purpose:** Identify package format by analyzing file paths.
|
|
50
|
+
|
|
51
|
+
**Detection heuristics:**
|
|
52
|
+
- Universal subdirs: `commands/`, `agents/`, `rules/`, `skills/`, `hooks/`
|
|
53
|
+
- Platform-specific dirs: `.claude/`, `.cursor/`, `.opencode/`, etc.
|
|
54
|
+
- Platform suffixes in filenames: `mcp.claude.jsonc`, `config.cursor.yaml`
|
|
55
|
+
- Confidence scoring based on file distribution
|
|
56
|
+
|
|
57
|
+
**Example:**
|
|
58
|
+
```typescript
|
|
59
|
+
import { detectPackageFormat } from './format-detector.js';
|
|
60
|
+
|
|
61
|
+
const files = [
|
|
62
|
+
{ path: '.claude/commands/review.md', content: '...' },
|
|
63
|
+
{ path: '.claude/agents/helper.md', content: '...' }
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
const format = detectPackageFormat(files);
|
|
67
|
+
// Result:
|
|
68
|
+
// {
|
|
69
|
+
// type: 'platform-specific',
|
|
70
|
+
// platform: 'claude',
|
|
71
|
+
// confidence: 0.95,
|
|
72
|
+
// analysis: { ... }
|
|
73
|
+
// }
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Format types:**
|
|
77
|
+
- `'universal'`: OpenPackage universal format
|
|
78
|
+
- `'platform-specific'`: Claude, Cursor, OpenCode, etc.
|
|
79
|
+
|
|
80
|
+
### 2. Flow Inverter (`flow-inverter.ts`)
|
|
81
|
+
|
|
82
|
+
**Purpose:** Reverse flow transformations to convert platform-specific → universal.
|
|
83
|
+
|
|
84
|
+
**Key insight:** The `platforms.jsonc` flows already define universal → platform transformations. We can **invert** these flows to go in reverse.
|
|
85
|
+
|
|
86
|
+
**Inversion rules:**
|
|
87
|
+
- **Paths:** Swap `from` ↔ `to`
|
|
88
|
+
```typescript
|
|
89
|
+
// Original
|
|
90
|
+
{ from: "commands/**/*.md", to: ".claude/commands/**/*.md" }
|
|
91
|
+
|
|
92
|
+
// Inverted
|
|
93
|
+
{ from: ".claude/commands/**/*.md", to: "commands/**/*.md" }
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
- **Map `$rename`:** Swap key pairs
|
|
97
|
+
```typescript
|
|
98
|
+
// Original
|
|
99
|
+
{ $rename: { "mcp": "mcpServers" } }
|
|
100
|
+
|
|
101
|
+
// Inverted
|
|
102
|
+
{ $rename: { "mcpServers": "mcp" } }
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
- **Operations processed in reverse order**
|
|
106
|
+
- **Non-reversible operations skipped** (`$set`, `$unset`, `$pipeline` with lossy transforms)
|
|
107
|
+
- **Format converters preserved** (`yaml`, `jsonc`, `toml`)
|
|
108
|
+
- **Filters skipped** (`filter-empty`, `filter-null`)
|
|
109
|
+
|
|
110
|
+
### 3. Platform Converter (`platform-converter.ts`)
|
|
111
|
+
|
|
112
|
+
**Purpose:** High-level orchestration of format conversions.
|
|
113
|
+
|
|
114
|
+
**Conversion pipeline stages:**
|
|
115
|
+
1. **Platform → Universal:** Invert source platform flows
|
|
116
|
+
2. **Universal → Target:** Apply target platform flows (handled by installer)
|
|
117
|
+
|
|
118
|
+
**Example usage:**
|
|
119
|
+
```typescript
|
|
120
|
+
import { createPlatformConverter } from './platform-converter.js';
|
|
121
|
+
|
|
122
|
+
const converter = createPlatformConverter(workspaceRoot);
|
|
123
|
+
|
|
124
|
+
const result = await converter.convert(
|
|
125
|
+
package,
|
|
126
|
+
targetPlatform,
|
|
127
|
+
{ dryRun: false }
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
if (result.success) {
|
|
131
|
+
console.log(`Converted ${result.stages.length} stages`);
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 4. Enhanced Flow-Based Installer
|
|
136
|
+
|
|
137
|
+
**Purpose:** Integrate converter into installation pipeline.
|
|
138
|
+
|
|
139
|
+
**Installation strategies:**
|
|
140
|
+
|
|
141
|
+
#### Strategy 1: Direct Installation (AS-IS)
|
|
142
|
+
```
|
|
143
|
+
Source: Claude plugin
|
|
144
|
+
Target: claude platform
|
|
145
|
+
Action: Copy files directly, skip all transformations
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### Strategy 2: Convert via Universal
|
|
149
|
+
```
|
|
150
|
+
Source: Claude plugin
|
|
151
|
+
Target: cursor platform
|
|
152
|
+
Pipeline:
|
|
153
|
+
1. Detect format (claude platform-specific)
|
|
154
|
+
2. Invert claude flows (.claude/commands/*.md → commands/*.md)
|
|
155
|
+
3. Apply cursor flows (commands/*.md → .cursor/commands/*.md)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
#### Strategy 3: Standard Flow Installation
|
|
159
|
+
```
|
|
160
|
+
Source: Universal package
|
|
161
|
+
Target: Any platform
|
|
162
|
+
Action: Apply platform flows (existing behavior)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Installation Flow
|
|
166
|
+
|
|
167
|
+
### Full Installation Pipeline
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
async function installPackageWithFlows(context) {
|
|
171
|
+
// 1. Detect package format
|
|
172
|
+
const format = await detectPackageFormat(packageRoot);
|
|
173
|
+
|
|
174
|
+
// 2. Check for direct installation
|
|
175
|
+
if (shouldInstallDirectly(format, targetPlatform)) {
|
|
176
|
+
return await installDirectly(context, format);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// 3. Check for conversion
|
|
180
|
+
if (needsConversion(format, targetPlatform)) {
|
|
181
|
+
return await installWithConversion(context, format);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// 4. Standard flow-based installation
|
|
185
|
+
return await executeStandardFlows(context);
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Decision Tree
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
Package Format Detection
|
|
193
|
+
├─ Universal Format
|
|
194
|
+
│ └─→ Standard flow-based installation
|
|
195
|
+
│
|
|
196
|
+
├─ Platform-Specific (matches target)
|
|
197
|
+
│ └─→ Direct installation (AS-IS)
|
|
198
|
+
│
|
|
199
|
+
└─ Platform-Specific (different from target)
|
|
200
|
+
└─→ Convert via universal
|
|
201
|
+
├─ Stage 1: Invert source platform flows
|
|
202
|
+
└─ Stage 2: Apply target platform flows
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Usage Examples
|
|
206
|
+
|
|
207
|
+
### Example 1: Claude Plugin → Claude Platform
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
# Install Claude plugin to Claude platform
|
|
211
|
+
opkg install path/to/claude-plugin --platforms claude
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Behavior:**
|
|
215
|
+
- Detects: Claude platform-specific format
|
|
216
|
+
- Target: claude platform
|
|
217
|
+
- Action: **Direct installation (AS-IS)**
|
|
218
|
+
- Result: Files copied to `.claude/` without any transformation
|
|
219
|
+
|
|
220
|
+
**Console output:**
|
|
221
|
+
```
|
|
222
|
+
🔌 Detected Claude Code plugin
|
|
223
|
+
📦 Installing plugin: my-plugin@1.0.0
|
|
224
|
+
✓ Installing my-plugin AS-IS for claude platform (matching format)
|
|
225
|
+
✓ Added files: 5
|
|
226
|
+
├── .claude/commands/review.md
|
|
227
|
+
├── .claude/commands/test.md
|
|
228
|
+
├── .claude/agents/helper.md
|
|
229
|
+
└── ...
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Example 2: Claude Plugin → Cursor Platform
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
# Install Claude plugin to Cursor platform
|
|
236
|
+
opkg install path/to/claude-plugin --platforms cursor
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Behavior:**
|
|
240
|
+
- Detects: Claude platform-specific format
|
|
241
|
+
- Target: cursor platform
|
|
242
|
+
- Action: **Convert via universal**
|
|
243
|
+
1. Invert claude flows (`.claude/commands/*.md` → `commands/*.md`)
|
|
244
|
+
2. Apply cursor flows (`commands/*.md` → `.cursor/commands/*.md`)
|
|
245
|
+
|
|
246
|
+
**Console output:**
|
|
247
|
+
```
|
|
248
|
+
🔌 Detected Claude Code plugin
|
|
249
|
+
📦 Installing plugin: my-plugin@1.0.0
|
|
250
|
+
🔄 Converting my-plugin from claude to cursor format
|
|
251
|
+
✓ Conversion stage: platform-to-universal (5 files)
|
|
252
|
+
✓ Applying cursor platform flows
|
|
253
|
+
✓ Added files: 5
|
|
254
|
+
├── .cursor/commands/review.md
|
|
255
|
+
├── .cursor/commands/test.md
|
|
256
|
+
└── ...
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Example 3: Claude Plugin → Multiple Platforms
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# Install to both Claude and Cursor
|
|
263
|
+
opkg install path/to/claude-plugin --platforms claude,cursor
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Behavior:**
|
|
267
|
+
- For `claude`: Direct installation (AS-IS)
|
|
268
|
+
- For `cursor`: Convert via universal
|
|
269
|
+
- Efficient: Conversion happens once, applied to cursor only
|
|
270
|
+
|
|
271
|
+
### Example 4: Universal Package (Existing Behavior)
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
# Standard universal package installation
|
|
275
|
+
opkg install @user/package --platforms claude,cursor
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**Behavior:**
|
|
279
|
+
- Detects: Universal format
|
|
280
|
+
- Action: **Standard flow-based installation** (no changes)
|
|
281
|
+
- Claude: Apply claude flows
|
|
282
|
+
- Cursor: Apply cursor flows
|
|
283
|
+
|
|
284
|
+
## Configuration
|
|
285
|
+
|
|
286
|
+
**No configuration needed!** The system works automatically by:
|
|
287
|
+
1. Analyzing file structure
|
|
288
|
+
2. Reading existing `platforms.jsonc` flows
|
|
289
|
+
3. Inverting flows as needed
|
|
290
|
+
|
|
291
|
+
## API Reference
|
|
292
|
+
|
|
293
|
+
### Format Detector
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
/**
|
|
297
|
+
* Detect package format from file list
|
|
298
|
+
*/
|
|
299
|
+
function detectPackageFormat(files: PackageFile[]): PackageFormat
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Check if format is platform-specific
|
|
303
|
+
*/
|
|
304
|
+
function isPlatformSpecific(format: PackageFormat): boolean
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Check if conversion is needed
|
|
308
|
+
*/
|
|
309
|
+
function needsConversion(
|
|
310
|
+
format: PackageFormat,
|
|
311
|
+
targetPlatform: Platform
|
|
312
|
+
): boolean
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Check if should install AS-IS
|
|
316
|
+
*/
|
|
317
|
+
function shouldInstallDirectly(
|
|
318
|
+
format: PackageFormat,
|
|
319
|
+
targetPlatform: Platform
|
|
320
|
+
): boolean
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Flow Inverter
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
/**
|
|
327
|
+
* Invert a single flow
|
|
328
|
+
*/
|
|
329
|
+
function invertFlow(flow: Flow, sourcePlatform: Platform): InvertedFlow
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Invert multiple flows
|
|
333
|
+
*/
|
|
334
|
+
function invertFlows(flows: Flow[], sourcePlatform: Platform): InvertedFlow[]
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Check if flow is inverted
|
|
338
|
+
*/
|
|
339
|
+
function isInvertedFlow(flow: Flow): boolean
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Platform Converter
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
/**
|
|
346
|
+
* Convert package to target platform
|
|
347
|
+
*/
|
|
348
|
+
class PlatformConverter {
|
|
349
|
+
async convert(
|
|
350
|
+
pkg: Package,
|
|
351
|
+
targetPlatform: Platform,
|
|
352
|
+
options?: { dryRun?: boolean }
|
|
353
|
+
): Promise<ConversionResult>
|
|
354
|
+
|
|
355
|
+
buildPipeline(
|
|
356
|
+
sourceFormat: PackageFormat,
|
|
357
|
+
targetPlatform: Platform
|
|
358
|
+
): ConversionPipeline
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Create converter instance
|
|
363
|
+
*/
|
|
364
|
+
function createPlatformConverter(workspaceRoot: string): PlatformConverter
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## Implementation Details
|
|
368
|
+
|
|
369
|
+
### Format Detection Algorithm
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
1. Scan all package files
|
|
373
|
+
2. For each file:
|
|
374
|
+
a. Check if path starts with platform dir (.claude/, .cursor/, etc.)
|
|
375
|
+
b. Check if path starts with universal subdir (commands/, agents/, etc.)
|
|
376
|
+
c. Check for platform suffix in filename (mcp.claude.jsonc)
|
|
377
|
+
3. Calculate ratios:
|
|
378
|
+
- universalRatio = universalFiles / totalFiles
|
|
379
|
+
- platformRatio = platformSpecificFiles / totalFiles
|
|
380
|
+
4. Determine format:
|
|
381
|
+
- If universalRatio > 0.7 → universal
|
|
382
|
+
- If platformRatio > 0.7 → platform-specific (dominant platform)
|
|
383
|
+
- Else → universal (default, low confidence)
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Flow Inversion Algorithm
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
1. Swap from ↔ to paths
|
|
390
|
+
2. Process map operations in reverse order:
|
|
391
|
+
For each operation:
|
|
392
|
+
- $rename: Swap key pairs
|
|
393
|
+
- $copy: Swap from/to
|
|
394
|
+
- $set/$unset: Skip (not reversible)
|
|
395
|
+
- $switch: Reverse pattern/value pairs
|
|
396
|
+
- $pipeline: Invert operations if possible (see below)
|
|
397
|
+
3. Filter pipe transforms:
|
|
398
|
+
- Keep: Format converters (yaml, jsonc, toml)
|
|
399
|
+
- Keep: Merge strategies
|
|
400
|
+
- Skip: Filters (filter-empty, filter-null)
|
|
401
|
+
- Skip: Validation (validate-*)
|
|
402
|
+
4. Preserve: merge, when, namespace
|
|
403
|
+
5. Remove: embed, section
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
## Testing
|
|
407
|
+
|
|
408
|
+
### Unit Tests
|
|
409
|
+
|
|
410
|
+
**Format Detection:**
|
|
411
|
+
```typescript
|
|
412
|
+
// tests/format-detector.test.ts
|
|
413
|
+
- Detect universal format
|
|
414
|
+
- Detect Claude platform-specific
|
|
415
|
+
- Detect Cursor platform-specific
|
|
416
|
+
- Detect platform suffix in filenames
|
|
417
|
+
- Handle mixed files
|
|
418
|
+
- Provide detailed analysis
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
**Flow Inversion:**
|
|
422
|
+
```typescript
|
|
423
|
+
// tests/flow-inverter.test.ts
|
|
424
|
+
- Swap from/to paths
|
|
425
|
+
- Invert $rename operations
|
|
426
|
+
- Skip non-reversible operations
|
|
427
|
+
- Preserve merge strategy
|
|
428
|
+
- Handle pipe transforms
|
|
429
|
+
- Invert $copy operations
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**Platform Converter:**
|
|
433
|
+
```typescript
|
|
434
|
+
// tests/platform-converter.test.ts
|
|
435
|
+
- Build conversion pipeline
|
|
436
|
+
- Convert between formats
|
|
437
|
+
- Handle matching formats (no conversion)
|
|
438
|
+
- Integration scenarios
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### Integration Tests
|
|
442
|
+
|
|
443
|
+
```typescript
|
|
444
|
+
// tests/install-claude-plugin.test.ts
|
|
445
|
+
- Install Claude plugin to claude platform (AS-IS)
|
|
446
|
+
- Install Claude plugin to cursor platform (convert)
|
|
447
|
+
- Multi-platform installation
|
|
448
|
+
- Git-based plugin installation
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
## Performance Considerations
|
|
452
|
+
|
|
453
|
+
1. **Format Detection:** Fast - only analyzes file paths, no content parsing
|
|
454
|
+
2. **Direct Installation:** Fastest - simple file copy, no transformations
|
|
455
|
+
3. **Conversion:** Moderate - one conversion to universal, then standard flows
|
|
456
|
+
4. **Caching:** Package format cached after first detection
|
|
457
|
+
|
|
458
|
+
## Limitations
|
|
459
|
+
|
|
460
|
+
### Non-Reversible Operations
|
|
461
|
+
|
|
462
|
+
Some flow operations cannot be reliably inverted:
|
|
463
|
+
|
|
464
|
+
- **`$set`:** Cannot determine original value
|
|
465
|
+
- **`$unset`:** Cannot restore removed fields
|
|
466
|
+
- **`$pipeline`:** Complex multi-step transformations with lossy operations (e.g., `$map` with case changes)
|
|
467
|
+
- **Filters:** Cannot "un-filter" removed content
|
|
468
|
+
|
|
469
|
+
**Impact:** Conversion may not be 100% lossless for packages with complex transformations.
|
|
470
|
+
|
|
471
|
+
**Mitigation:** Most platform flows use simple path mappings and basic $rename operations, which invert perfectly.
|
|
472
|
+
|
|
473
|
+
### Round-Trip Accuracy
|
|
474
|
+
|
|
475
|
+
Converting `Platform A → Universal → Platform B` may not always equal converting `Platform B → Universal → Platform A` in reverse, due to:
|
|
476
|
+
- Non-reversible operations
|
|
477
|
+
- Lossy transformations (e.g., filtering, complex string manipulations)
|
|
478
|
+
|
|
479
|
+
**Best practice:** Keep flows simple and bidirectional-friendly.
|
|
480
|
+
|
|
481
|
+
## Future Enhancements
|
|
482
|
+
|
|
483
|
+
1. **Direct Platform-to-Platform:** Skip universal intermediate step for known conversions
|
|
484
|
+
2. **Conversion Validation:** Round-trip testing to verify accuracy
|
|
485
|
+
3. **Custom Converters:** Plugin system for complex conversions
|
|
486
|
+
4. **Conversion Cache:** Store converted packages for faster reinstalls
|
|
487
|
+
5. **Partial Conversion:** Convert only specific files/flows
|
|
488
|
+
|
|
489
|
+
## FAQ
|
|
490
|
+
|
|
491
|
+
### Q: Will this break existing packages?
|
|
492
|
+
**A:** No. Universal packages continue to work exactly as before. The converter only activates for platform-specific packages.
|
|
493
|
+
|
|
494
|
+
### Q: Can I force AS-IS installation?
|
|
495
|
+
**A:** Yes, by targeting the same platform as the source:
|
|
496
|
+
```bash
|
|
497
|
+
opkg install claude-plugin --platforms claude
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### Q: What if conversion fails?
|
|
501
|
+
**A:** The installer will report errors and fall back gracefully. You can inspect conversion errors with `--dry-run` flag.
|
|
502
|
+
|
|
503
|
+
### Q: How accurate is format detection?
|
|
504
|
+
**A:** Very accurate for typical packages. Confidence scores indicate certainty. Mixed-format packages default to universal (safest).
|
|
505
|
+
|
|
506
|
+
### Q: Can I convert between any two platforms?
|
|
507
|
+
**A:** Yes! The system converts through universal format:
|
|
508
|
+
```
|
|
509
|
+
Platform A → Universal → Platform B
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Q: Does this work with git sources?
|
|
513
|
+
**A:** Yes! Format detection and conversion work for all package sources (path, git, registry).
|
|
514
|
+
|
|
515
|
+
## See Also
|
|
516
|
+
|
|
517
|
+
- [Platform Flows](./flows.md) - Declarative transformation system
|
|
518
|
+
- [Flow Reference](./flow-reference.md) - Complete flow syntax
|
|
519
|
+
- [Platform Detection](./detection.md) - Platform identification
|
|
520
|
+
- [Installation Behavior](../install/install-behavior.md) - Install semantics
|
package/specs/push/README.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
This directory contains specifications for the `push` command, with a focus on:
|
|
4
4
|
|
|
5
5
|
- **Stable-only pushes (no prereleases)**
|
|
6
|
+
- **Source package detection**: At effective cwd (shell or --cwd; see [../../cli-options.md])
|
|
6
7
|
- **Local-version selection and scoping behavior**
|
|
7
8
|
- **Consistent, helpful CLI UX and error messaging**
|
|
8
9
|
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
## Push command behavior
|
|
2
2
|
|
|
3
|
+
### Effective Working Directory
|
|
4
|
+
The command determines the source package via the **effective cwd** (shell `cwd` or global `--cwd <dir>` override; see [../../cli-options.md]):
|
|
5
|
+
- Detects package context at effective cwd (root `openpackage.yml` or nested `.openpackage/packages/<name>/`).
|
|
6
|
+
- Packs from that dir's content/layout.
|
|
7
|
+
- Enables monorepo pushes: `opkg push --cwd ./sub-pkg` targets sub-dir package without `cd`.
|
|
8
|
+
|
|
9
|
+
If no valid package detected, errors early ("No package project at <dir>").
|
|
10
|
+
|
|
3
11
|
### Overview
|
|
4
12
|
|
|
5
13
|
The `opkg push` command uploads a local package version from the **local registry** to the **remote registry**.
|
|
6
14
|
It allows:
|
|
7
15
|
- **Stable versions** (`x.y.z`).
|
|
8
|
-
- **Unversioned packages** (when `
|
|
16
|
+
- **Unversioned packages** (when `openpackage.yml` omits `version`, represented as `0.0.0`).
|
|
9
17
|
It still rejects prerelease versions like `1.2.3-dev.abc`.
|
|
10
18
|
|
|
11
19
|
This document focuses on user-facing behavior:
|
|
@@ -111,12 +119,12 @@ High-level flow:
|
|
|
111
119
|
- Missing paths fail the push with a clear missing-path message.
|
|
112
120
|
3. Tarball is narrowed to:
|
|
113
121
|
- The requested file set.
|
|
114
|
-
-
|
|
122
|
+
- `openpackage.yml`.
|
|
115
123
|
4. Upload uses the standard `/packages/push` endpoint.
|
|
116
124
|
|
|
117
125
|
Notes:
|
|
118
126
|
- This replaces the previous single-file `f` flow; single-file pushes are just partial pushes with one path.
|
|
119
|
-
- Manifest is required; if
|
|
127
|
+
- Manifest is required; if `openpackage.yml` is missing locally, the CLI errors.
|
|
120
128
|
|
|
121
129
|
|
|
122
130
|
## Stable-only guarantees (behavioral view)
|
|
@@ -42,7 +42,7 @@ Assuming a valid stable package `pkg` and `versionToPush` have been selected:
|
|
|
42
42
|
|
|
43
43
|
- `createTarballFromPackage(pkg)` builds a tarball from the package files.
|
|
44
44
|
- For **partial pushes** (paths provided via spec or `--paths`):
|
|
45
|
-
- The tarball is narrowed to only the requested registry paths plus
|
|
45
|
+
- The tarball is narrowed to only the requested registry paths plus `openpackage.yml`.
|
|
46
46
|
- File count reflects only the selected files.
|
|
47
47
|
- The CLI prints:
|
|
48
48
|
- `✓ Creating tarball...`
|
|
@@ -18,7 +18,7 @@ This document describes how `push` handles scoping for upload. Scoping is applie
|
|
|
18
18
|
- A scoped upload name is computed (e.g. `@user/test`) via the existing prompt/default-scope flow.
|
|
19
19
|
- No local rename occurs; the local registry and workspace remain on the unscoped name.
|
|
20
20
|
3. Before tarball creation:
|
|
21
|
-
- The package is cloned in-memory and its
|
|
21
|
+
- The package is cloned in-memory and its `openpackage.yml` `name` field is rewritten to the scoped upload name.
|
|
22
22
|
- The upload payload (full or partial) uses this in-memory manifest, so the remote receives the scoped identity.
|
|
23
23
|
4. Version selection and path validation still operate on the local name and local files.
|
|
24
24
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
- **Stable version**: A semver-valid version with no prerelease segment, e.g. `1.2.3`.
|
|
6
6
|
- **Prerelease version**: A semver-valid version with a prerelease segment, e.g. `1.2.3-dev.abc123`.
|
|
7
|
-
- **Unversioned package**: A package whose `
|
|
7
|
+
- **Unversioned package**: A package whose `openpackage.yml` omits `version`; represented and stored as semver `0.0.0` locally (one per package) and can be pushed like any other stable version.
|
|
8
8
|
- **Local registry**: The on-disk package store used by `opkg` (managed via `packageManager`).
|
|
9
9
|
|
|
10
10
|
This document defines the rules `opkg push` uses to decide **which local version** is eligible to be pushed to the remote registry.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Registry
|
|
2
|
+
|
|
3
|
+
The local registry stores **immutable, versioned package snapshots** for offline use, distribution, and caching. It uses directory-based storage for simplicity, analogous to a local npm or Docker registry (file-system only currently; remotes deferred).
|
|
4
|
+
|
|
5
|
+
## Structure
|
|
6
|
+
|
|
7
|
+
Scoped, nested directories:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
~/.openpackage/registry/
|
|
11
|
+
├── <name>/ # Unscoped package
|
|
12
|
+
│ ├── <version>/ # e.g., 1.0.0 or WIP prerelease
|
|
13
|
+
│ │ ├── openpackage.yml # Manifest (version, deps)
|
|
14
|
+
│ │ ├── commands/ # Universal subdirs
|
|
15
|
+
│ │ ├── rules/
|
|
16
|
+
│ │ ├── AGENTS.md # Root files
|
|
17
|
+
│ │ └── root/ # Direct copy content
|
|
18
|
+
│ └── <version>/
|
|
19
|
+
│
|
|
20
|
+
└── @<scope>/ # Scoped
|
|
21
|
+
└── <name>/
|
|
22
|
+
└── <version>/
|
|
23
|
+
└── ...
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Each `<version>/` is a full, self-contained package copy (no links/extraction).
|
|
27
|
+
|
|
28
|
+
## Why Directory-Based (vs. Tarballs)?
|
|
29
|
+
|
|
30
|
+
| Aspect | Directories | Tarballs |
|
|
31
|
+
|--------|-------------|----------|
|
|
32
|
+
| Simplicity | ✅ No extraction | ❌ Pack/unpack steps |
|
|
33
|
+
| Path Refs | ✅ Direct `path:` works | ❌ Cache + extract |
|
|
34
|
+
| Debugging | ✅ Browse files | ❌ Must unpack to inspect |
|
|
35
|
+
| Code Reuse | ✅ Same read logic as sources | ❌ Special handling |
|
|
36
|
+
| Storage | ⚠️ Uncompressed (text pkgs small) | ✅ Compressed |
|
|
37
|
+
|
|
38
|
+
The architecture prioritizes dev ergonomics over size.
|
|
39
|
+
|
|
40
|
+
## Version Directory Contents (Payload)
|
|
41
|
+
|
|
42
|
+
Full package root; structural rules—no YAML filters.
|
|
43
|
+
|
|
44
|
+
- **Always**: `openpackage.yml`.
|
|
45
|
+
- **Universal Subdirs**: `commands/`, `rules/`, etc. (from platforms.jsonc).
|
|
46
|
+
- **Root Files**: `AGENTS.md`, platform variants (e.g., `CLAUDE.md` overrides).
|
|
47
|
+
- **root/**: 1:1 copy to workspace root (prefix stripped on install).
|
|
48
|
+
- **Other**: Docs (`README.md`), licenses, arbitrary files/dirs.
|
|
49
|
+
|
|
50
|
+
**Excludes**:
|
|
51
|
+
- `.openpackage/**` (metadata).
|
|
52
|
+
- `openpackage.index.yml` (workspace-local).
|
|
53
|
+
- `packages/**` (reserved).
|
|
54
|
+
|
|
55
|
+
Details: [Registry Payload and Copy](package/registry-payload-and-copy.md).
|
|
56
|
+
|
|
57
|
+
## Operations
|
|
58
|
+
|
|
59
|
+
### Creation (pack)
|
|
60
|
+
From mutable source to registry snapshot.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
opkg pack <name> # Copies source to registry/<name>/<version>/
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- Version from `openpackage.yml` or computed stable/WIP.
|
|
67
|
+
- Full dir copy; marks immutable.
|
|
68
|
+
- Options: `--output <path>` (direct copy, no <name>/<ver>); `--dry-run`.
|
|
69
|
+
- See [Pack](pack/).
|
|
70
|
+
|
|
71
|
+
### Consumption (install, apply)
|
|
72
|
+
```bash
|
|
73
|
+
opkg install <name>@<ver> # Resolves, copies from registry/<name>/<ver>/ to workspace
|
|
74
|
+
opkg apply <name> # Syncs from inferred path
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
- Direct file access.
|
|
78
|
+
- Updates index/yml.
|
|
79
|
+
- See [Install](install/), [Apply](apply/).
|
|
80
|
+
|
|
81
|
+
### Listing
|
|
82
|
+
```bash
|
|
83
|
+
opkg list <name> # Versions from dir names
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Git Clones in Registry
|
|
87
|
+
Git deps cloned here → treated immutable (current behavior).
|
|
88
|
+
|
|
89
|
+
## Immutability
|
|
90
|
+
|
|
91
|
+
- Registry dirs read-only: `save`/`add` detect and error.
|
|
92
|
+
- Re-pack overwrites entire dir (idempotent).
|
|
93
|
+
- No partial updates.
|
|
94
|
+
|
|
95
|
+
Error example:
|
|
96
|
+
```
|
|
97
|
+
Error: Cannot save – source in registry (immutable).
|
|
98
|
+
Path: ~/.openpackage/registry/my-pkg/1.0.0/
|
|
99
|
+
Fix: Copy to packages/, update path.
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Scoping
|
|
103
|
+
|
|
104
|
+
Scoped: `registry/@org/my-pkg/<ver>/`; yml uses `@org/my-pkg`.
|
|
105
|
+
|
|
106
|
+
## Remote Registries (Deferred)
|
|
107
|
+
|
|
108
|
+
Future: Push/pull tarballs for transfer; extract to local dir.
|
|
109
|
+
See [Push](push/) for upload prep; [Self-Hosted](self-hosted-registries.md) if created.
|
|
110
|
+
|
|
111
|
+
Cross-links: [Package Sources](package-sources.md) for resolution; [Directory Layout](directory-layout.md).
|