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
package/dist/commands/status.js
CHANGED
|
@@ -1,722 +1,47 @@
|
|
|
1
|
-
import { join } from 'path';
|
|
2
|
-
import * as semver from 'semver';
|
|
3
|
-
import { parsePackageYml } from '../utils/package-yml.js';
|
|
4
|
-
import { ensureRegistryDirectories, listPackageVersions } from '../core/directory.js';
|
|
5
|
-
import { gatherGlobalVersionConstraints, gatherRootVersionConstraints } from '../core/openpackage.js';
|
|
6
|
-
import { resolveDependencies } from '../core/dependency-resolver.js';
|
|
7
|
-
import { registryManager } from '../core/registry.js';
|
|
8
|
-
import { exists } from '../utils/fs.js';
|
|
9
|
-
import { logger } from '../utils/logger.js';
|
|
10
1
|
import { withErrorHandling, ValidationError } from '../utils/errors.js';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
* Recursively scans to handle scoped packages (e.g., @scope/name)
|
|
22
|
-
*/
|
|
23
|
-
async function scanLocalPackageMetadata(cwd) {
|
|
24
|
-
const packagesDir = getLocalPackagesDir(cwd);
|
|
25
|
-
const localPackages = new Map();
|
|
26
|
-
if (!(await exists(packagesDir))) {
|
|
27
|
-
return localPackages;
|
|
28
|
-
}
|
|
29
|
-
try {
|
|
30
|
-
// Use the generic recursive scanner to find all pkg.yml files
|
|
31
|
-
const packageDirs = await findDirectoriesContainingFile(packagesDir, FILE_PATTERNS.PACKAGE_YML, async (filePath) => {
|
|
32
|
-
try {
|
|
33
|
-
return await parsePackageYml(filePath);
|
|
34
|
-
}
|
|
35
|
-
catch (error) {
|
|
36
|
-
logger.warn(`Failed to parse local package metadata: ${filePath}`, { error });
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
// Build the map from results
|
|
41
|
-
for (const result of packageDirs) {
|
|
42
|
-
if (result.parsedContent) {
|
|
43
|
-
localPackages.set(result.parsedContent.name, result.parsedContent);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
catch (error) {
|
|
48
|
-
logger.error('Failed to scan local package metadata', { error, packagesDir });
|
|
49
|
-
}
|
|
50
|
-
return localPackages;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Detect platform status and configuration
|
|
54
|
-
*/
|
|
55
|
-
async function detectPlatformStatus(cwd) {
|
|
56
|
-
const detections = await detectAllPlatforms(cwd);
|
|
57
|
-
const checks = detections.map(async ({ name, detected }) => {
|
|
58
|
-
const def = getPlatformDefinition(name);
|
|
59
|
-
const rootAbs = join(cwd, def.rootDir);
|
|
60
|
-
const [dirExists] = await Promise.all([
|
|
61
|
-
exists(rootAbs)
|
|
62
|
-
]);
|
|
63
|
-
return {
|
|
64
|
-
name,
|
|
65
|
-
detected: detected && dirExists,
|
|
66
|
-
configured: detected && dirExists,
|
|
67
|
-
directoryExists: dirExists
|
|
68
|
-
};
|
|
69
|
-
});
|
|
70
|
-
return Promise.all(checks);
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Check registry for available versions
|
|
74
|
-
*/
|
|
75
|
-
async function checkRegistryVersions(packageName) {
|
|
76
|
-
try {
|
|
77
|
-
const [hasPackage, metadata, available] = await Promise.all([
|
|
78
|
-
registryManager.hasPackage(packageName),
|
|
79
|
-
registryManager.getPackageMetadata(packageName).catch(() => null),
|
|
80
|
-
listPackageVersions(packageName).catch(() => [])
|
|
81
|
-
]);
|
|
82
|
-
if (!hasPackage) {
|
|
83
|
-
return { available: [] };
|
|
84
|
-
}
|
|
85
|
-
return {
|
|
86
|
-
latest: metadata?.version,
|
|
87
|
-
available: available || []
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
catch (error) {
|
|
91
|
-
logger.debug(`Failed to check registry for package ${packageName}`, { error });
|
|
92
|
-
return { available: [] };
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Analyze status of a single package with enhanced checks
|
|
97
|
-
*/
|
|
98
|
-
async function analyzePackageStatus(requiredPackage, availablePackage, localMetadata, type, registryCheck = false) {
|
|
99
|
-
const status = {
|
|
100
|
-
name: requiredPackage.name,
|
|
101
|
-
installedVersion: requiredPackage.version,
|
|
102
|
-
type,
|
|
103
|
-
status: 'missing'
|
|
104
|
-
};
|
|
105
|
-
// Check registry if requested
|
|
106
|
-
if (registryCheck) {
|
|
107
|
-
const registryInfo = await checkRegistryVersions(requiredPackage.name);
|
|
108
|
-
status.registryVersion = registryInfo.latest;
|
|
109
|
-
if (registryInfo.available.length === 0) {
|
|
110
|
-
status.status = 'registry-unavailable';
|
|
111
|
-
status.issues = [`Package '${requiredPackage.name}' not found in registry`];
|
|
112
|
-
return status;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
// Case 1: Package not found by scanner
|
|
116
|
-
if (!availablePackage) {
|
|
117
|
-
if (localMetadata) {
|
|
118
|
-
status.status = 'files-missing';
|
|
119
|
-
status.issues = [`Package '${requiredPackage.name}' has local metadata but no files detected`];
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
status.status = 'missing';
|
|
123
|
-
status.issues = [`Package '${requiredPackage.name}' not found`];
|
|
124
|
-
}
|
|
125
|
-
// Check for registry updates if available
|
|
126
|
-
if (registryCheck && status.registryVersion && status.status === 'missing') {
|
|
127
|
-
status.status = 'update-available';
|
|
128
|
-
status.issues?.push(`Version ${status.registryVersion} available in registry`);
|
|
129
|
-
}
|
|
130
|
-
return status;
|
|
131
|
-
}
|
|
132
|
-
// Case 2: Package exists - compare versions
|
|
133
|
-
status.availableVersion = localMetadata?.version || availablePackage.version;
|
|
134
|
-
status.path = availablePackage.path;
|
|
135
|
-
const requiredVersion = requiredPackage.version;
|
|
136
|
-
const installedVersion = formatVersionLabel(availablePackage.version);
|
|
137
|
-
// Ensure displayed version reflects the actual installed/detected version
|
|
138
|
-
status.installedVersion = installedVersion;
|
|
139
|
-
// If local metadata is missing, likely .openpackage/packages/<name>/pkg.yml is missing or misnamed
|
|
140
|
-
if (!localMetadata) {
|
|
141
|
-
status.status = 'files-missing';
|
|
142
|
-
status.issues = [`'${FILE_PATTERNS.PACKAGE_YML}' is missing or misnamed`];
|
|
143
|
-
// Avoid confusing 0.0.0 display when metadata is missing
|
|
144
|
-
status.installedVersion = requiredVersion;
|
|
145
|
-
return status;
|
|
146
|
-
}
|
|
147
|
-
if (!requiredVersion) {
|
|
148
|
-
status.status = 'installed';
|
|
149
|
-
return status;
|
|
150
|
-
}
|
|
151
|
-
// Support multiple constraints joined by ' & ' (logical AND)
|
|
152
|
-
const requiredRanges = requiredVersion.includes('&')
|
|
153
|
-
? requiredVersion.split('&').map(s => s.trim()).filter(Boolean)
|
|
154
|
-
: [requiredVersion];
|
|
155
|
-
// Check version compatibility
|
|
156
|
-
try {
|
|
157
|
-
const satisfiesAll = requiredRanges.every(range => satisfiesVersion(installedVersion, range));
|
|
158
|
-
if (satisfiesAll) {
|
|
159
|
-
status.status = 'installed';
|
|
160
|
-
// Check for registry updates if requested
|
|
161
|
-
if (registryCheck &&
|
|
162
|
-
status.registryVersion &&
|
|
163
|
-
semver.valid(status.registryVersion) &&
|
|
164
|
-
semver.valid(installedVersion) &&
|
|
165
|
-
semver.gt(status.registryVersion, installedVersion)) {
|
|
166
|
-
status.status = 'update-available';
|
|
167
|
-
status.issues = [`Newer version ${status.registryVersion} available in registry`];
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
else {
|
|
171
|
-
// Determine version mismatch type
|
|
172
|
-
if (requiredRanges.length === 1 &&
|
|
173
|
-
isExactVersion(requiredRanges[0]) &&
|
|
174
|
-
semver.valid(installedVersion) &&
|
|
175
|
-
semver.valid(requiredRanges[0])) {
|
|
176
|
-
status.status = semver.gt(installedVersion, requiredRanges[0]) ? 'outdated' : 'dependency-mismatch';
|
|
177
|
-
const comparison = semver.gt(installedVersion, requiredRanges[0]) ? 'newer than' : 'older than';
|
|
178
|
-
status.issues = [`Installed version ${installedVersion} is ${comparison} required ${requiredRanges[0]}`];
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
status.status = 'dependency-mismatch';
|
|
182
|
-
status.issues = [
|
|
183
|
-
`Installed version ${installedVersion} does not satisfy range ${requiredVersion} (${requiredRanges.map(describeVersionRange).join(' & ')})`
|
|
184
|
-
];
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
catch (error) {
|
|
189
|
-
status.status = 'dependency-mismatch';
|
|
190
|
-
status.issues = [`Version analysis failed: ${error}`];
|
|
191
|
-
}
|
|
192
|
-
// Validate local metadata consistency (only flag when exact version is required)
|
|
193
|
-
if (localMetadata && localMetadata.version !== installedVersion && requiredVersion && isExactVersion(requiredVersion)) {
|
|
194
|
-
status.issues = status.issues || [];
|
|
195
|
-
status.issues.push(`Local metadata version ${localMetadata.version} differs from ai version ${installedVersion}`);
|
|
196
|
-
if (status.status === 'installed') {
|
|
197
|
-
status.status = 'structure-invalid';
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
return status;
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Build dependency tree using install's dependency resolver
|
|
204
|
-
*/
|
|
205
|
-
async function buildPackageDependencyTree(packageName, cwd, availablePackages, localMetadata, version, registryCheck = false) {
|
|
206
|
-
try {
|
|
207
|
-
// Use the install command's dependency resolver to get the complete tree
|
|
208
|
-
const constraints = await gatherGlobalVersionConstraints(cwd);
|
|
209
|
-
const rootConstraints = await gatherRootVersionConstraints(cwd);
|
|
210
|
-
const result = await resolveDependencies(packageName, cwd, true, new Set(), new Map(), version, new Map(), constraints, rootConstraints);
|
|
211
|
-
const resolvedPackages = result.resolvedPackages;
|
|
212
|
-
const missingPackages = result.missingPackages;
|
|
213
|
-
// Convert resolved packages to status info in parallel
|
|
214
|
-
const dependencyPromises = resolvedPackages
|
|
215
|
-
.filter(resolved => !resolved.isRoot) // Skip the root package
|
|
216
|
-
.map(async (resolved) => {
|
|
217
|
-
const availablePackage = availablePackages.get(resolved.name) || null;
|
|
218
|
-
const localMeta = localMetadata.get(resolved.name) || null;
|
|
219
|
-
const dependency = {
|
|
220
|
-
name: resolved.name,
|
|
221
|
-
version: resolved.requiredRange || resolved.version
|
|
222
|
-
};
|
|
223
|
-
const depStatus = await analyzePackageStatus(dependency, availablePackage, localMeta, 'dependency', registryCheck);
|
|
224
|
-
if (resolved.conflictResolution) {
|
|
225
|
-
depStatus.conflictResolution = resolved.conflictResolution;
|
|
226
|
-
}
|
|
227
|
-
return depStatus;
|
|
228
|
-
});
|
|
229
|
-
// Add status info for missing packages
|
|
230
|
-
const missingPromises = missingPackages.map(async (missingName) => {
|
|
231
|
-
const dependency = {
|
|
232
|
-
name: missingName,
|
|
233
|
-
version: 'latest'
|
|
234
|
-
};
|
|
235
|
-
return await analyzePackageStatus(dependency, null, // no available package
|
|
236
|
-
null, // no local metadata
|
|
237
|
-
'dependency', registryCheck);
|
|
238
|
-
});
|
|
239
|
-
const allPromises = [...dependencyPromises, ...missingPromises];
|
|
240
|
-
return Promise.all(allPromises);
|
|
241
|
-
}
|
|
242
|
-
catch (error) {
|
|
243
|
-
logger.warn(`Failed to resolve dependencies for ${packageName}`, { error });
|
|
244
|
-
// Fallback to basic dependency scanning
|
|
245
|
-
const pkg = availablePackages.get(packageName);
|
|
246
|
-
if (!pkg?.packages) {
|
|
247
|
-
return [];
|
|
248
|
-
}
|
|
249
|
-
const fallbackPromises = pkg.packages.map(async (dep) => {
|
|
250
|
-
const availableDep = availablePackages.get(dep.name) || null;
|
|
251
|
-
const localMeta = localMetadata.get(dep.name) || null;
|
|
252
|
-
return analyzePackageStatus(dep, availableDep, localMeta, 'dependency', registryCheck);
|
|
253
|
-
});
|
|
254
|
-
return Promise.all(fallbackPromises);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Perform complete status analysis with enhanced checks
|
|
259
|
-
*/
|
|
260
|
-
async function performStatusAnalysis(cwd, options = {}) {
|
|
261
|
-
// 1. Check basic project structure in parallel
|
|
262
|
-
const [openpackageDir, packageYmlPath, packagesDir, aiDir] = [
|
|
263
|
-
getLocalOpenPackageDir(cwd),
|
|
264
|
-
getLocalPackageYmlPath(cwd),
|
|
265
|
-
getLocalPackagesDir(cwd),
|
|
266
|
-
getInstallRootDir(cwd)
|
|
267
|
-
];
|
|
268
|
-
const [openpackageExists, packageYmlExists, packagesDirExists, aiDirExists] = await Promise.all([
|
|
269
|
-
exists(openpackageDir),
|
|
270
|
-
exists(packageYmlPath),
|
|
271
|
-
exists(packagesDir),
|
|
272
|
-
exists(aiDir)
|
|
273
|
-
]);
|
|
274
|
-
if (!openpackageExists || !packageYmlExists) {
|
|
275
|
-
throw new ValidationError(`No .openpackage/pkg.yml found in ${cwd}. This directory doesn't appear to be a package project.\n\n` +
|
|
276
|
-
`💡 To initialize this as a package project:\n` +
|
|
277
|
-
` • Run 'opkg init' to create a new package project\n` +
|
|
278
|
-
` • Run 'opkg install' to install existing packages`);
|
|
279
|
-
}
|
|
280
|
-
// 2. Parse main pkg.yml and detect platforms in parallel
|
|
281
|
-
const [cwdConfig, platformStatuses] = await Promise.all([
|
|
282
|
-
parsePackageYml(packageYmlPath).catch(error => {
|
|
283
|
-
throw new ValidationError(`Failed to parse pkg.yml: ${error}`);
|
|
284
|
-
}),
|
|
285
|
-
options.platforms ? detectPlatformStatus(cwd) : Promise.resolve([])
|
|
286
|
-
]);
|
|
287
|
-
// 3. Discover installed files using same method as uninstall and read local metadata in parallel
|
|
288
|
-
// First collect all package names including dependencies
|
|
289
|
-
const packageNames = new Set([
|
|
290
|
-
...(cwdConfig.packages || []).map(f => normalizePackageName(f.name)),
|
|
291
|
-
...(cwdConfig[DEPENDENCY_ARRAYS.PACKAGES] || []).map(f => normalizePackageName(f.name))
|
|
292
|
-
]);
|
|
293
|
-
// Resolve dependencies for each package to get their names
|
|
294
|
-
for (const pkg of cwdConfig.packages || []) {
|
|
295
|
-
try {
|
|
296
|
-
const constraints = await gatherGlobalVersionConstraints(cwd);
|
|
297
|
-
const rootConstraints = await gatherRootVersionConstraints(cwd);
|
|
298
|
-
const result = await resolveDependencies(pkg.name, cwd, true, new Set(), new Map(), pkg.version, new Map(), constraints, rootConstraints);
|
|
299
|
-
const resolvedPackages = result.resolvedPackages;
|
|
300
|
-
const missingPackages = result.missingPackages;
|
|
301
|
-
// Add all resolved dependency names to the set
|
|
302
|
-
for (const resolved of resolvedPackages) {
|
|
303
|
-
if (!resolved.isRoot) {
|
|
304
|
-
packageNames.add(normalizePackageName(resolved.name));
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
// Add missing package names to the set
|
|
308
|
-
for (const missing of missingPackages) {
|
|
309
|
-
packageNames.add(normalizePackageName(missing));
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
catch (error) {
|
|
313
|
-
logger.debug(`Failed to resolve dependencies for ${pkg.name}`, { error });
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
const [detectedByFrontmatter, localMetadata] = await Promise.all([
|
|
317
|
-
discoverPackagesForStatus(Array.from(packageNames)),
|
|
318
|
-
scanLocalPackageMetadata(cwd)
|
|
319
|
-
]);
|
|
320
|
-
// Build availability map using detection results, preferring metadata versions when present
|
|
321
|
-
const availablePackages = new Map();
|
|
322
|
-
for (const [name, det] of detectedByFrontmatter) {
|
|
323
|
-
const meta = localMetadata.get(name);
|
|
324
|
-
availablePackages.set(name, {
|
|
325
|
-
name,
|
|
326
|
-
version: meta?.version || '0.0.0',
|
|
327
|
-
path: det.anyPath || join(aiDir, name)
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
// 4. Analyze all packages in parallel
|
|
331
|
-
const allPackages = [
|
|
332
|
-
...(cwdConfig.packages || []).map(f => ({ ...f, type: 'package' })),
|
|
333
|
-
...(cwdConfig[DEPENDENCY_ARRAYS.DEV_PACKAGES] || []).map(f => ({ ...f, type: 'dev-package' }))
|
|
334
|
-
];
|
|
335
|
-
const analysisPromises = allPackages.map(async (pkg) => {
|
|
336
|
-
const available = availablePackages.get(pkg.name) || null;
|
|
337
|
-
const localMeta = localMetadata.get(pkg.name) || null;
|
|
338
|
-
const status = await analyzePackageStatus(pkg, available, localMeta, pkg.type, options.registry);
|
|
339
|
-
const detected = detectedByFrontmatter.get(pkg.name);
|
|
340
|
-
if (detected) {
|
|
341
|
-
status.fileSummary = {
|
|
342
|
-
aiFiles: { found: detected.aiFiles.length, paths: detected.aiFiles },
|
|
343
|
-
platformFiles: detected.platforms,
|
|
344
|
-
rootFiles: detected.rootFiles ? { found: detected.rootFiles.length, paths: detected.rootFiles } : undefined
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
// Build dependency tree if installed
|
|
348
|
-
if (status.status === 'installed') {
|
|
349
|
-
try {
|
|
350
|
-
status.dependencies = await buildPackageDependencyTree(pkg.name, cwd, availablePackages, localMetadata, pkg.version, options.registry);
|
|
351
|
-
}
|
|
352
|
-
catch (error) {
|
|
353
|
-
logger.warn(`Failed to build dependency tree for ${pkg.name}`, { error });
|
|
354
|
-
status.issues = status.issues || [];
|
|
355
|
-
status.issues.push(`Dependency analysis failed: ${error}`);
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
return status;
|
|
359
|
-
});
|
|
360
|
-
const results = await Promise.all(analysisPromises);
|
|
361
|
-
// 5. Build project status
|
|
362
|
-
const projectInfo = {
|
|
363
|
-
name: cwdConfig.name,
|
|
364
|
-
version: cwdConfig.version,
|
|
365
|
-
openpackageExists,
|
|
366
|
-
packageYmlExists,
|
|
367
|
-
packagesDirectoryExists: packagesDirExists,
|
|
368
|
-
aiDirectoryExists: aiDirExists,
|
|
369
|
-
platforms: platformStatuses
|
|
370
|
-
};
|
|
371
|
-
return {
|
|
372
|
-
projectInfo,
|
|
373
|
-
packages: results
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
/**
|
|
377
|
-
* Render enhanced tree view of packages with status
|
|
378
|
-
*/
|
|
379
|
-
function renderTreeView(projectInfo, packages, options = {}) {
|
|
380
|
-
// Project header with status indicators
|
|
381
|
-
const statusIndicators = [
|
|
382
|
-
!projectInfo.openpackageExists && '❌ .openpackage missing',
|
|
383
|
-
!projectInfo.packageYmlExists && '❌ pkg.yml missing',
|
|
384
|
-
!projectInfo.aiDirectoryExists && '⚠️ ai directory missing'
|
|
385
|
-
].filter(Boolean);
|
|
386
|
-
const statusSuffix = statusIndicators.length > 0 ? ` (${statusIndicators.join(', ')})` : '';
|
|
387
|
-
console.log(`${projectInfo.name}@${projectInfo.version}${statusSuffix}`);
|
|
388
|
-
// Platform information if requested
|
|
389
|
-
if (options.platforms && projectInfo.platforms.length > 0) {
|
|
390
|
-
console.log('\n✓ Platforms:');
|
|
391
|
-
for (const platform of projectInfo.platforms) {
|
|
392
|
-
const status = platform.detected ? '✅' : '❌';
|
|
393
|
-
console.log(` ${status} ${platform.name}`);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
if (packages.length === 0) {
|
|
397
|
-
console.log('\n└── (no packages)');
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
packages.forEach((pkg, i) => {
|
|
401
|
-
const isLast = i === packages.length - 1;
|
|
402
|
-
renderPackageTree(pkg, '', isLast, options.depth, 1);
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* Status icon and suffix mapping
|
|
407
|
-
*/
|
|
408
|
-
const STATUS_ICONS = {
|
|
409
|
-
'installed': '✅',
|
|
410
|
-
'missing': '❌',
|
|
411
|
-
'outdated': '⚠️',
|
|
412
|
-
'dependency-mismatch': '❌',
|
|
413
|
-
'update-available': '🔄',
|
|
414
|
-
'registry-unavailable': '⚠️',
|
|
415
|
-
'structure-invalid': '⚠️',
|
|
416
|
-
'platform-mismatch': '⚠️',
|
|
417
|
-
'files-missing': '⚠️',
|
|
418
|
-
'orphaned-files': '⚠️',
|
|
419
|
-
'frontmatter-mismatch': '⚠️'
|
|
420
|
-
};
|
|
421
|
-
/**
|
|
422
|
-
* Get status suffix for display
|
|
423
|
-
*/
|
|
424
|
-
function getStatusSuffix(pkg) {
|
|
425
|
-
switch (pkg.status) {
|
|
426
|
-
case 'missing':
|
|
427
|
-
return ' (missing)';
|
|
428
|
-
case 'outdated':
|
|
429
|
-
return ` (outdated: ${pkg.availableVersion} available)`;
|
|
430
|
-
case 'dependency-mismatch':
|
|
431
|
-
return ' (version mismatch)';
|
|
432
|
-
case 'update-available':
|
|
433
|
-
return pkg.registryVersion ? ` (update: ${pkg.registryVersion})` : ' (update available)';
|
|
434
|
-
case 'registry-unavailable':
|
|
435
|
-
return ' (not in registry)';
|
|
436
|
-
case 'structure-invalid':
|
|
437
|
-
return ' (structure issue)';
|
|
438
|
-
case 'platform-mismatch':
|
|
439
|
-
return ' (platform issue)';
|
|
440
|
-
case 'files-missing':
|
|
441
|
-
return ' (files missing)';
|
|
442
|
-
case 'orphaned-files':
|
|
443
|
-
return ' (orphaned files)';
|
|
444
|
-
case 'frontmatter-mismatch':
|
|
445
|
-
return ' (frontmatter mismatch)';
|
|
446
|
-
default:
|
|
447
|
-
return '';
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
/**
|
|
451
|
-
* Render individual package in enhanced tree format
|
|
452
|
-
*/
|
|
453
|
-
function renderPackageTree(pkg, prefix, isLast, maxDepth, currentDepth = 1) {
|
|
454
|
-
const connector = isLast ? '└── ' : '├── ';
|
|
455
|
-
const typePrefix = pkg.type === 'dev-package' ? '[dev] ' : '';
|
|
456
|
-
const statusIcon = STATUS_ICONS[pkg.status] || '❓';
|
|
457
|
-
const statusSuffix = getStatusSuffix(pkg);
|
|
458
|
-
const conflictInfo = pkg.conflictResolution ? ` [${pkg.conflictResolution}]` : '';
|
|
459
|
-
const installedLabel = formatVersionLabel(pkg.installedVersion);
|
|
460
|
-
console.log(`${prefix}${connector}${statusIcon} ${typePrefix}${pkg.name}@${installedLabel}${statusSuffix}${conflictInfo}`);
|
|
461
|
-
// Show issues if any
|
|
462
|
-
if (pkg.issues?.length) {
|
|
463
|
-
const issuePrefix = prefix + (isLast ? ' ' : '│ ');
|
|
464
|
-
pkg.issues.forEach(issue => {
|
|
465
|
-
console.log(`${issuePrefix}⚠️ ${issue}`);
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
// Optional file-level summary (verbose)
|
|
469
|
-
if (pkg.fileSummary && globalThis.__statusVerbose) {
|
|
470
|
-
const fsPrefix = prefix + (isLast ? ' ' : '│ ');
|
|
471
|
-
const fs = pkg.fileSummary;
|
|
472
|
-
console.log(`${fsPrefix}📄 ai files: ${fs.aiFiles.found}`);
|
|
473
|
-
const platforms = Object.keys(fs.platformFiles || {});
|
|
474
|
-
if (platforms.length > 0) {
|
|
475
|
-
console.log(`${fsPrefix}🖥️ platform files:`);
|
|
476
|
-
for (const p of platforms) {
|
|
477
|
-
const pf = fs.platformFiles[p] || {};
|
|
478
|
-
const parts = [];
|
|
479
|
-
if (pf.rules?.found)
|
|
480
|
-
parts.push(`rules:${pf.rules.found}`);
|
|
481
|
-
if (pf.commands?.found)
|
|
482
|
-
parts.push(`commands:${pf.commands.found}`);
|
|
483
|
-
if (pf.agents?.found)
|
|
484
|
-
parts.push(`agents:${pf.agents.found}`);
|
|
485
|
-
console.log(`${fsPrefix} - ${p} ${parts.length ? `(${parts.join(', ')})` : ''}`);
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
if (fs.rootFiles && fs.rootFiles.found > 0) {
|
|
489
|
-
console.log(`${fsPrefix}📁 root files: ${fs.rootFiles.found}`);
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
// Show dependencies if within depth limit
|
|
493
|
-
if (pkg.dependencies?.length) {
|
|
494
|
-
if (!maxDepth || currentDepth < maxDepth) {
|
|
495
|
-
const childPrefix = prefix + (isLast ? ' ' : '│ ');
|
|
496
|
-
pkg.dependencies.forEach((dep, j) => {
|
|
497
|
-
const isLastChild = j === pkg.dependencies.length - 1;
|
|
498
|
-
renderPackageTree(dep, childPrefix, isLastChild, maxDepth, currentDepth + 1);
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
else {
|
|
502
|
-
const childPrefix = prefix + (isLast ? ' ' : '│ ');
|
|
503
|
-
console.log(`${childPrefix}└── (${pkg.dependencies.length} dependencies - use --depth to see more)`);
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
/**
|
|
508
|
-
* Collect all packages including dependencies recursively
|
|
509
|
-
*/
|
|
510
|
-
function collectAllPackages(packages) {
|
|
511
|
-
const allPackages = [];
|
|
512
|
-
function collect(packageList) {
|
|
513
|
-
for (const pkg of packageList) {
|
|
514
|
-
allPackages.push(pkg);
|
|
515
|
-
if (pkg.dependencies) {
|
|
516
|
-
collect(pkg.dependencies);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
collect(packages);
|
|
521
|
-
return allPackages;
|
|
522
|
-
}
|
|
523
|
-
/**
|
|
524
|
-
* Render enhanced flat table view of packages
|
|
525
|
-
*/
|
|
526
|
-
function renderFlatView(packages, options = {}) {
|
|
527
|
-
if (packages.length === 0) {
|
|
528
|
-
console.log('No packages found.');
|
|
529
|
-
return;
|
|
530
|
-
}
|
|
531
|
-
const allPackages = collectAllPackages(packages);
|
|
532
|
-
// Enhanced table header
|
|
533
|
-
const headers = ['FORMULA', 'INSTALLED', 'STATUS', 'TYPE'];
|
|
534
|
-
const widths = [20, 12, 18, 15];
|
|
535
|
-
if (options.registry) {
|
|
536
|
-
headers.push('REGISTRY');
|
|
537
|
-
widths.push(12);
|
|
538
|
-
}
|
|
539
|
-
headers.push('ISSUES');
|
|
540
|
-
widths.push(30);
|
|
541
|
-
// Print header
|
|
542
|
-
console.log(headers.map((h, i) => h.padEnd(widths[i])).join(''));
|
|
543
|
-
console.log(headers.map((_, i) => '-'.repeat(widths[i] - 1).padEnd(widths[i])).join(''));
|
|
544
|
-
// Display each package
|
|
545
|
-
allPackages.forEach(pkg => {
|
|
546
|
-
const values = [
|
|
547
|
-
pkg.name.padEnd(widths[0]),
|
|
548
|
-
(pkg.installedVersion ?? '').padEnd(widths[1]),
|
|
549
|
-
pkg.status.padEnd(widths[2]),
|
|
550
|
-
pkg.type.padEnd(widths[3])
|
|
551
|
-
];
|
|
552
|
-
if (options.registry) {
|
|
553
|
-
values.push((pkg.registryVersion || '-').padEnd(widths[4]));
|
|
554
|
-
}
|
|
555
|
-
const issues = pkg.issues ? pkg.issues.slice(0, 2).join('; ') : '-';
|
|
556
|
-
values.push(issues.length > 27 ? issues.substring(0, 24) + '...' : issues);
|
|
557
|
-
console.log(values.join(''));
|
|
558
|
-
});
|
|
559
|
-
console.log('\nTotal: ${allPackages.length} packages');
|
|
560
|
-
// Summary by status
|
|
561
|
-
const statusCounts = new Map();
|
|
562
|
-
allPackages.forEach(pkg => {
|
|
563
|
-
statusCounts.set(pkg.status, (statusCounts.get(pkg.status) || 0) + 1);
|
|
564
|
-
});
|
|
565
|
-
console.log('\nStatus Summary:');
|
|
566
|
-
statusCounts.forEach((count, status) => {
|
|
567
|
-
console.log(` ${status}: ${count}`);
|
|
568
|
-
});
|
|
569
|
-
}
|
|
570
|
-
/**
|
|
571
|
-
* Calculate status counts efficiently
|
|
572
|
-
*/
|
|
573
|
-
function calculateStatusCounts(packages) {
|
|
574
|
-
const counts = {
|
|
575
|
-
installed: 0,
|
|
576
|
-
missing: 0,
|
|
577
|
-
outdated: 0,
|
|
578
|
-
mismatch: 0,
|
|
579
|
-
updateAvailable: 0,
|
|
580
|
-
registryUnavailable: 0,
|
|
581
|
-
structureInvalid: 0
|
|
582
|
-
};
|
|
583
|
-
packages.forEach(pkg => {
|
|
584
|
-
switch (pkg.status) {
|
|
585
|
-
case 'installed':
|
|
586
|
-
counts.installed++;
|
|
587
|
-
break;
|
|
588
|
-
case 'missing':
|
|
589
|
-
counts.missing++;
|
|
590
|
-
break;
|
|
591
|
-
case 'outdated':
|
|
592
|
-
counts.outdated++;
|
|
593
|
-
break;
|
|
594
|
-
case 'dependency-mismatch':
|
|
595
|
-
counts.mismatch++;
|
|
596
|
-
break;
|
|
597
|
-
case 'update-available':
|
|
598
|
-
counts.updateAvailable++;
|
|
599
|
-
break;
|
|
600
|
-
case 'registry-unavailable':
|
|
601
|
-
counts.registryUnavailable++;
|
|
602
|
-
break;
|
|
603
|
-
case 'structure-invalid':
|
|
604
|
-
counts.structureInvalid++;
|
|
605
|
-
break;
|
|
606
|
-
}
|
|
607
|
-
});
|
|
608
|
-
return counts;
|
|
609
|
-
}
|
|
610
|
-
/**
|
|
611
|
-
* Display status summary and recommendations
|
|
612
|
-
*/
|
|
613
|
-
function displayStatusSummary(packages, statusCounts) {
|
|
614
|
-
const totalPackages = packages.length;
|
|
615
|
-
console.log(`Summary: ${statusCounts.installed}/${totalPackages} installed`);
|
|
616
|
-
if (statusCounts.missing > 0) {
|
|
617
|
-
console.log(`❌ ${statusCounts.missing} packages missing from ai directory`);
|
|
618
|
-
}
|
|
619
|
-
if (statusCounts.mismatch > 0) {
|
|
620
|
-
console.log(`⚠️ ${statusCounts.mismatch} packages have version mismatches`);
|
|
621
|
-
}
|
|
622
|
-
if (statusCounts.updateAvailable > 0) {
|
|
623
|
-
console.log(`✓ ${statusCounts.updateAvailable} packages have updates available`);
|
|
624
|
-
}
|
|
625
|
-
if (statusCounts.registryUnavailable > 0) {
|
|
626
|
-
console.log(`⚠️ ${statusCounts.registryUnavailable} packages not found in registry`);
|
|
627
|
-
}
|
|
628
|
-
if (statusCounts.structureInvalid > 0) {
|
|
629
|
-
console.log(`⚠️ ${statusCounts.structureInvalid} packages have structure issues`);
|
|
630
|
-
}
|
|
631
|
-
// Show actionable recommendations
|
|
632
|
-
if (totalPackages === 0) {
|
|
633
|
-
console.log('');
|
|
634
|
-
console.log('💡 Tips:');
|
|
635
|
-
console.log('• Add packages to pkg.yml and run "opkg install" to install them');
|
|
636
|
-
console.log('• Use "opkg list" to see available packages in the registry');
|
|
637
|
-
console.log('• Run "opkg init" to initialize this as a package project');
|
|
638
|
-
}
|
|
639
|
-
else {
|
|
640
|
-
const hasIssues = statusCounts.missing + statusCounts.mismatch + statusCounts.structureInvalid > 0;
|
|
641
|
-
if (hasIssues) {
|
|
642
|
-
console.log('');
|
|
643
|
-
console.log('💡 Recommended actions:');
|
|
644
|
-
if (statusCounts.missing > 0) {
|
|
645
|
-
console.log('• Run "opkg install" to install missing packages');
|
|
646
|
-
}
|
|
647
|
-
if (statusCounts.updateAvailable > 0) {
|
|
648
|
-
console.log('• Run "opkg install --force <package-name>" to update specific packages');
|
|
649
|
-
}
|
|
650
|
-
if (statusCounts.structureInvalid > 0) {
|
|
651
|
-
console.log('• Run "opkg install --force" to repair structure issues');
|
|
652
|
-
}
|
|
653
|
-
if (statusCounts.registryUnavailable > 0) {
|
|
654
|
-
console.log('• Check if missing packages exist in remote registry with "opkg search"');
|
|
655
|
-
}
|
|
2
|
+
import { runStatusPipeline } from '../core/status/status-pipeline.js';
|
|
3
|
+
import { logger } from '../utils/logger.js';
|
|
4
|
+
function printPackageLine(pkg, verbose) {
|
|
5
|
+
const icon = pkg.state === 'synced' ? '✅' : pkg.state === 'missing' ? '❌' : '⚠️';
|
|
6
|
+
const version = pkg.version ? `@${pkg.version}` : '';
|
|
7
|
+
console.log(`${icon} ${pkg.name}${version} ${pkg.state} ${pkg.path}`);
|
|
8
|
+
if (verbose && pkg.diffs.length > 0) {
|
|
9
|
+
for (const diff of pkg.diffs) {
|
|
10
|
+
const reason = diff.reason === 'missing' ? 'missing' : 'changed';
|
|
11
|
+
console.log(` - ${reason}: ${diff.workspacePath || diff.sourcePath}`);
|
|
656
12
|
}
|
|
657
13
|
}
|
|
658
14
|
}
|
|
659
|
-
/**
|
|
660
|
-
* Enhanced status command implementation with comprehensive analysis
|
|
661
|
-
*/
|
|
662
15
|
async function statusCommand(options = {}) {
|
|
663
16
|
const cwd = process.cwd();
|
|
664
|
-
logger.info(`Checking package status for directory: ${cwd}
|
|
665
|
-
// Set a global verbose flag for renderer (avoids threading through many calls)
|
|
666
|
-
globalThis.__statusVerbose = Boolean(options.verbose);
|
|
667
|
-
// Ensure registry directories exist
|
|
668
|
-
await ensureRegistryDirectories();
|
|
17
|
+
logger.info(`Checking package status for directory: ${cwd}`);
|
|
669
18
|
try {
|
|
670
|
-
const
|
|
671
|
-
|
|
672
|
-
platforms: options.platforms
|
|
673
|
-
});
|
|
674
|
-
// Display results
|
|
19
|
+
const result = await runStatusPipeline();
|
|
20
|
+
const packages = result.data?.packages ?? [];
|
|
675
21
|
console.log(`✓ Package status for: ${cwd}`);
|
|
676
|
-
if (
|
|
677
|
-
|
|
22
|
+
if (packages.length === 0) {
|
|
23
|
+
console.log('(no packages in index)');
|
|
24
|
+
return { success: true, data: { packages: [] } };
|
|
678
25
|
}
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
depth: options.depth,
|
|
682
|
-
platforms: options.platforms
|
|
683
|
-
});
|
|
26
|
+
for (const pkg of packages) {
|
|
27
|
+
printPackageLine(pkg, Boolean(options.verbose));
|
|
684
28
|
}
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
// Show repair suggestions if requested
|
|
689
|
-
if (options.repair) {
|
|
690
|
-
console.log('✓ Repair suggestions:');
|
|
691
|
-
// TODO: Add specific repair recommendations based on issues found
|
|
692
|
-
}
|
|
693
|
-
return {
|
|
694
|
-
success: true,
|
|
695
|
-
data: {
|
|
696
|
-
projectInfo,
|
|
697
|
-
packages,
|
|
698
|
-
summary: statusCounts
|
|
699
|
-
}
|
|
700
|
-
};
|
|
29
|
+
const synced = packages.filter(p => p.state === 'synced').length;
|
|
30
|
+
console.log(`Summary: ${synced}/${packages.length} synced`);
|
|
31
|
+
return { success: true, data: { packages } };
|
|
701
32
|
}
|
|
702
33
|
catch (error) {
|
|
703
|
-
|
|
34
|
+
if (error instanceof ValidationError) {
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
704
37
|
throw error;
|
|
705
38
|
}
|
|
706
39
|
}
|
|
707
|
-
/**
|
|
708
|
-
* Setup the enhanced status command
|
|
709
|
-
*/
|
|
710
40
|
export function setupStatusCommand(program) {
|
|
711
41
|
program
|
|
712
42
|
.command('status')
|
|
713
|
-
.description('Show
|
|
714
|
-
.option('--
|
|
715
|
-
.option('--depth <number>', 'limit tree depth (default: unlimited)', parseInt)
|
|
716
|
-
.option('--registry', 'check registry for available updates')
|
|
717
|
-
.option('--platforms', 'show platform-specific status information')
|
|
718
|
-
.option('--repair', 'show repair suggestions without applying them')
|
|
719
|
-
.option('--verbose', 'show file-level details')
|
|
43
|
+
.description('Show package sync state')
|
|
44
|
+
.option('--verbose', 'show file-level differences')
|
|
720
45
|
.action(withErrorHandling(async (options) => {
|
|
721
46
|
await statusCommand(options);
|
|
722
47
|
}));
|