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,801 @@
|
|
|
1
|
+
# Map Pipeline Documentation
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The **Map Pipeline** is a MongoDB aggregation-inspired transformation system that enables powerful document-level field transformations during package installation. It provides a declarative, composable approach to transforming package content as files flow from source to target.
|
|
6
|
+
|
|
7
|
+
**Design Philosophy:**
|
|
8
|
+
- **MongoDB-aligned:** Uses `$operation` syntax matching MongoDB aggregation operators
|
|
9
|
+
- **Sequential execution:** Operations applied in order, each receiving the result of the previous
|
|
10
|
+
- **Document-level:** Transforms entire documents (frontmatter, JSON, YAML, TOML)
|
|
11
|
+
- **Context-aware:** Access file metadata through `$$` context variables
|
|
12
|
+
- **Type-safe:** Full TypeScript support with comprehensive validation
|
|
13
|
+
|
|
14
|
+
## Implementation
|
|
15
|
+
|
|
16
|
+
**Initial Commit:** `e464927d2f5d2480c439a83c5cfc2e04053ac22d`
|
|
17
|
+
**MongoDB Alignment:** January 9, 2026 (Breaking Change)
|
|
18
|
+
|
|
19
|
+
**Core files:**
|
|
20
|
+
- `src/core/flows/map-pipeline/index.ts` - Main pipeline executor
|
|
21
|
+
- `src/core/flows/map-pipeline/types.ts` - TypeScript type definitions
|
|
22
|
+
- `src/core/flows/map-pipeline/operations/` - Individual operation implementations
|
|
23
|
+
- `schemas/map-pipeline-v1.json` - JSON Schema validation
|
|
24
|
+
- `tests/flows/map-pipeline.test.ts` - Comprehensive test suite
|
|
25
|
+
|
|
26
|
+
## Architecture
|
|
27
|
+
|
|
28
|
+
### Pipeline Structure
|
|
29
|
+
|
|
30
|
+
```jsonc
|
|
31
|
+
{
|
|
32
|
+
"map": [
|
|
33
|
+
{ "$operation1": config1 },
|
|
34
|
+
{ "$operation2": config2 },
|
|
35
|
+
{ "$operation3": config3 }
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Execution Flow
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
Input Document
|
|
44
|
+
↓
|
|
45
|
+
$operation1 (receives input, produces result1)
|
|
46
|
+
↓
|
|
47
|
+
$operation2 (receives result1, produces result2)
|
|
48
|
+
↓
|
|
49
|
+
$operation3 (receives result2, produces result3)
|
|
50
|
+
↓
|
|
51
|
+
Output Document
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Key characteristics:**
|
|
55
|
+
- Operations execute sequentially
|
|
56
|
+
- Each operation receives full document
|
|
57
|
+
- Operations are isolated (no side effects)
|
|
58
|
+
- Document is deep-cloned at start to prevent mutations
|
|
59
|
+
- All operations use `$` prefix (MongoDB convention)
|
|
60
|
+
|
|
61
|
+
### Context Variables
|
|
62
|
+
|
|
63
|
+
Every operation has access to file context:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
interface MapContext {
|
|
67
|
+
filename: string; // Filename without extension: "code-reviewer"
|
|
68
|
+
dirname: string; // Parent directory: "agents"
|
|
69
|
+
path: string; // Relative path: "agents/code-reviewer.md"
|
|
70
|
+
ext: string; // Extension with dot: ".md"
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Usage in operations:**
|
|
75
|
+
- Prefix with `$$` to inject: `$$filename`, `$$dirname`, `$$path`, `$$ext`
|
|
76
|
+
- Escape literal `$$`: use `\$$` to get literal string `$$filename`
|
|
77
|
+
|
|
78
|
+
## Seven Core Operations
|
|
79
|
+
|
|
80
|
+
### 1. `$set` - Set Field Values
|
|
81
|
+
|
|
82
|
+
Sets one or more fields with literal values or context variables.
|
|
83
|
+
|
|
84
|
+
**Examples:**
|
|
85
|
+
|
|
86
|
+
```jsonc
|
|
87
|
+
// Set from context
|
|
88
|
+
{ "$set": { "name": "$$filename" } }
|
|
89
|
+
|
|
90
|
+
// Set multiple fields
|
|
91
|
+
{ "$set": {
|
|
92
|
+
"name": "$$filename",
|
|
93
|
+
"version": "1.0.0",
|
|
94
|
+
"status": "active"
|
|
95
|
+
}}
|
|
96
|
+
|
|
97
|
+
// Nested fields (dot notation)
|
|
98
|
+
{ "$set": { "config.model": "sonnet" } }
|
|
99
|
+
|
|
100
|
+
// Escaped literal
|
|
101
|
+
{ "$set": { "template": "\\$$placeholder" } }
|
|
102
|
+
// Results in: { "template": "$$placeholder" }
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**MongoDB equivalent:** `$set` (exact match)
|
|
106
|
+
|
|
107
|
+
**See:** `src/core/flows/map-pipeline/operations/set.ts`
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
### 2. `$rename` - Rename Fields
|
|
112
|
+
|
|
113
|
+
Renames fields with support for wildcards.
|
|
114
|
+
|
|
115
|
+
**Examples:**
|
|
116
|
+
|
|
117
|
+
```jsonc
|
|
118
|
+
// Simple rename
|
|
119
|
+
{ "$rename": { "mcp": "mcpServers" } }
|
|
120
|
+
|
|
121
|
+
// Multiple renames
|
|
122
|
+
{ "$rename": {
|
|
123
|
+
"old1": "new1",
|
|
124
|
+
"old2": "new2"
|
|
125
|
+
}}
|
|
126
|
+
|
|
127
|
+
// Wildcard rename (preserves structure)
|
|
128
|
+
{ "$rename": { "mcp.*": "mcpServers.*" } }
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Wildcard example:**
|
|
132
|
+
```json
|
|
133
|
+
// Input
|
|
134
|
+
{ "mcp": { "server1": {}, "server2": {} } }
|
|
135
|
+
|
|
136
|
+
// After { "$rename": { "mcp.*": "mcpServers.*" } }
|
|
137
|
+
{ "mcpServers": { "server1": {}, "server2": {} } }
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**MongoDB equivalent:** `$rename` (exact match)
|
|
141
|
+
|
|
142
|
+
**See:** `src/core/flows/map-pipeline/operations/rename.ts`
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### 3. `$unset` - Remove Fields
|
|
147
|
+
|
|
148
|
+
Removes one or more fields from the document.
|
|
149
|
+
|
|
150
|
+
**Examples:**
|
|
151
|
+
|
|
152
|
+
```jsonc
|
|
153
|
+
// Single field
|
|
154
|
+
{ "$unset": "deprecated" }
|
|
155
|
+
|
|
156
|
+
// Multiple fields
|
|
157
|
+
{ "$unset": ["legacy", "temp", "internal"] }
|
|
158
|
+
|
|
159
|
+
// Nested field
|
|
160
|
+
{ "$unset": "config.debug.verbose" }
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**MongoDB equivalent:** `$unset` (exact match)
|
|
164
|
+
|
|
165
|
+
**See:** `src/core/flows/map-pipeline/operations/unset.ts`
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
### 4. `$switch` - Pattern-Based Value Replacement
|
|
170
|
+
|
|
171
|
+
Pattern matching with value replacement (like switch statement).
|
|
172
|
+
|
|
173
|
+
**Examples:**
|
|
174
|
+
|
|
175
|
+
```jsonc
|
|
176
|
+
// String pattern matching (glob syntax)
|
|
177
|
+
{
|
|
178
|
+
"$switch": {
|
|
179
|
+
"field": "model",
|
|
180
|
+
"cases": [
|
|
181
|
+
{ "pattern": "anthropic/claude-sonnet-*", "value": "sonnet" },
|
|
182
|
+
{ "pattern": "anthropic/claude-opus-*", "value": "opus" }
|
|
183
|
+
],
|
|
184
|
+
"default": "inherit"
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Object pattern matching
|
|
189
|
+
{
|
|
190
|
+
"$switch": {
|
|
191
|
+
"field": "permission",
|
|
192
|
+
"cases": [
|
|
193
|
+
{
|
|
194
|
+
"pattern": { "edit": "deny", "bash": "deny" },
|
|
195
|
+
"value": "restricted"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"pattern": { "*": "deny" },
|
|
199
|
+
"value": "ignore"
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**Pattern matching rules:**
|
|
207
|
+
- **String patterns:** Use glob syntax (`*`, `?`)
|
|
208
|
+
- **Object patterns:** Match object shape (all keys must match)
|
|
209
|
+
- **First match wins:** Stops checking after first successful match
|
|
210
|
+
- **Default optional:** If provided, used when no patterns match
|
|
211
|
+
|
|
212
|
+
**MongoDB equivalent:** Similar to `$switch` (aggregation expression)
|
|
213
|
+
|
|
214
|
+
**See:** `src/core/flows/map-pipeline/operations/switch.ts`
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
### 5. `$pipeline` - Multi-Step Field Transformation
|
|
219
|
+
|
|
220
|
+
Transforms a field through a pipeline of operations (MongoDB-aligned syntax).
|
|
221
|
+
|
|
222
|
+
**Available operations:**
|
|
223
|
+
|
|
224
|
+
| Operation | Purpose | Input → Output |
|
|
225
|
+
|-----------|---------|----------------|
|
|
226
|
+
| `{ "$filter": { "match": { "value": X } } }` | Filter by value | Object → Object (filtered) |
|
|
227
|
+
| `{ "$filter": { "match": { "key": X } } }` | Filter by key | Object → Object (filtered) |
|
|
228
|
+
| `{ "$objectToArray": { "extract": "keys" } }` | Extract keys | Object → Array |
|
|
229
|
+
| `{ "$objectToArray": { "extract": "values" } }` | Extract values | Object → Array |
|
|
230
|
+
| `{ "$objectToArray": { "extract": "entries" } }` | To entries | Object → Array of [key, value] |
|
|
231
|
+
| `{ "$map": { "each": "capitalize" } }` | Transform elements | Array → Array (transformed) |
|
|
232
|
+
| `{ "$reduce": { "type": "join", "separator": "," } }` | Join to string | Array → String |
|
|
233
|
+
| `{ "$reduce": { "type": "split", "separator": "," } }` | Split to array | String → Array |
|
|
234
|
+
| `{ "$arrayToObject": { "value": X } }` | Array to object | Array → Object |
|
|
235
|
+
| `{ "$replace": { "pattern": "...", "with": "..." } }` | String replacement | String → String |
|
|
236
|
+
|
|
237
|
+
**Example:**
|
|
238
|
+
|
|
239
|
+
```jsonc
|
|
240
|
+
// Convert tools object to CSV string
|
|
241
|
+
{
|
|
242
|
+
"$pipeline": {
|
|
243
|
+
"field": "tools",
|
|
244
|
+
"operations": [
|
|
245
|
+
{ "$filter": { "match": { "value": true } } }, // Keep only true values
|
|
246
|
+
{ "$objectToArray": { "extract": "keys" } }, // Extract keys
|
|
247
|
+
{ "$map": { "each": "capitalize" } }, // Capitalize each
|
|
248
|
+
{ "$reduce": { "type": "join", "separator": ", " } } // Join to string
|
|
249
|
+
]
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**Input:**
|
|
255
|
+
```yaml
|
|
256
|
+
tools:
|
|
257
|
+
write: false
|
|
258
|
+
edit: false
|
|
259
|
+
bash: true
|
|
260
|
+
read: true
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**Output:**
|
|
264
|
+
```yaml
|
|
265
|
+
tools: Bash, Read
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Empty result handling:**
|
|
269
|
+
If transformation results in empty string or empty array, the field is automatically removed.
|
|
270
|
+
|
|
271
|
+
**MongoDB alignment:**
|
|
272
|
+
- `$filter` - matches MongoDB's `$filter`
|
|
273
|
+
- `$objectToArray` - matches MongoDB's `$objectToArray`
|
|
274
|
+
- `$map` - matches MongoDB's `$map`
|
|
275
|
+
- `$reduce` - inspired by MongoDB's `$reduce`
|
|
276
|
+
- `$arrayToObject` - matches MongoDB's `$arrayToObject`
|
|
277
|
+
- `$replace` - similar to MongoDB's `$replaceOne`/`$replaceAll`
|
|
278
|
+
|
|
279
|
+
**See:** `src/core/flows/map-pipeline/operations/transform.ts`
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
### 6. `$copy` - Copy Field with Optional Transformation
|
|
284
|
+
|
|
285
|
+
Copies a field to new location with optional pattern-based transformation.
|
|
286
|
+
|
|
287
|
+
**Examples:**
|
|
288
|
+
|
|
289
|
+
```jsonc
|
|
290
|
+
// Simple copy
|
|
291
|
+
{
|
|
292
|
+
"$copy": {
|
|
293
|
+
"from": "config",
|
|
294
|
+
"to": "settings"
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Copy with transformation
|
|
299
|
+
{
|
|
300
|
+
"$copy": {
|
|
301
|
+
"from": "permission",
|
|
302
|
+
"to": "permissionMode",
|
|
303
|
+
"transform": {
|
|
304
|
+
"cases": [
|
|
305
|
+
{ "pattern": { "edit": "deny", "bash": "deny" }, "value": "plan" },
|
|
306
|
+
{ "pattern": { "*": "deny" }, "value": "ignore" }
|
|
307
|
+
],
|
|
308
|
+
"default": "default"
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
**MongoDB equivalent:** Custom operation (not in MongoDB)
|
|
315
|
+
|
|
316
|
+
**See:** `src/core/flows/map-pipeline/operations/copy.ts`
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
### 7. `$pipe` - Apply Transform Registry Operations
|
|
321
|
+
|
|
322
|
+
Applies external transforms from the transform registry within the map pipeline.
|
|
323
|
+
Enables format conversions and validations to be interleaved with schema transformations.
|
|
324
|
+
|
|
325
|
+
**Examples:**
|
|
326
|
+
|
|
327
|
+
```jsonc
|
|
328
|
+
// Convert to TOML at end of pipeline
|
|
329
|
+
{
|
|
330
|
+
"$pipe": ["json-to-toml"]
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Parse TOML at start of pipeline
|
|
334
|
+
{
|
|
335
|
+
"$pipe": ["toml-to-json"]
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Chain multiple transforms
|
|
339
|
+
{
|
|
340
|
+
"$pipe": ["filter-comments", "jsonc", "validate-schema"]
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**Complete flow example:**
|
|
345
|
+
|
|
346
|
+
```jsonc
|
|
347
|
+
{
|
|
348
|
+
"from": ["mcp.jsonc", "mcp.json"],
|
|
349
|
+
"to": ".codex/mcp-servers.toml",
|
|
350
|
+
"map": [
|
|
351
|
+
// Schema transformations
|
|
352
|
+
{ "$rename": { "mcp": "mcp_servers" } },
|
|
353
|
+
{
|
|
354
|
+
"$pipeline": {
|
|
355
|
+
"field": "mcp_servers.*.headers.Authorization",
|
|
356
|
+
"operations": [
|
|
357
|
+
{ "$extract": {
|
|
358
|
+
"pattern": "^Bearer \\$\\{env:([A-Z_]+)\\}$",
|
|
359
|
+
"group": 1
|
|
360
|
+
}}
|
|
361
|
+
]
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
// More transformations...
|
|
365
|
+
|
|
366
|
+
// Convert to TOML at the end
|
|
367
|
+
{ "$pipe": ["json-to-toml"] }
|
|
368
|
+
]
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**Use cases:**
|
|
373
|
+
- Format conversion: `json-to-toml`, `toml-to-json`, `yaml-to-json`
|
|
374
|
+
- Pre-processing: `filter-comments`, `jsonc` (parse JSONC)
|
|
375
|
+
- Post-processing: `validate-schema`, `format-toml`
|
|
376
|
+
- Mid-pipeline validation: Apply validation between transformation steps
|
|
377
|
+
|
|
378
|
+
**MongoDB equivalent:** Custom operation (bridges map pipeline with external systems)
|
|
379
|
+
|
|
380
|
+
**See:** `src/core/flows/map-pipeline/operations/pipe.ts`
|
|
381
|
+
|
|
382
|
+
## Complete Examples
|
|
383
|
+
|
|
384
|
+
### Example 1: Agent Name Injection
|
|
385
|
+
|
|
386
|
+
```jsonc
|
|
387
|
+
{
|
|
388
|
+
"from": "agents/**/*.md",
|
|
389
|
+
"to": ".claude/agents/**/*.md",
|
|
390
|
+
"map": [
|
|
391
|
+
{ "$set": { "name": "$$filename" } }
|
|
392
|
+
]
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**File:** `agents/code-reviewer.md`
|
|
397
|
+
**Result:** Frontmatter gets `name: code-reviewer`
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
### Example 2: Model Simplification
|
|
402
|
+
|
|
403
|
+
```jsonc
|
|
404
|
+
{
|
|
405
|
+
"from": "agents/**/*.md",
|
|
406
|
+
"to": ".claude/agents/**/*.md",
|
|
407
|
+
"map": [
|
|
408
|
+
{ "$set": { "name": "$$filename" } },
|
|
409
|
+
{
|
|
410
|
+
"$switch": {
|
|
411
|
+
"field": "model",
|
|
412
|
+
"cases": [
|
|
413
|
+
{ "pattern": "anthropic/claude-sonnet-*", "value": "sonnet" },
|
|
414
|
+
{ "pattern": "anthropic/claude-opus-*", "value": "opus" }
|
|
415
|
+
],
|
|
416
|
+
"default": "inherit"
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
]
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
**Transforms:**
|
|
424
|
+
`anthropic/claude-sonnet-4-20250514` → `sonnet`
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
### Example 3: Complete Claude Agent Transformation
|
|
429
|
+
|
|
430
|
+
```jsonc
|
|
431
|
+
{
|
|
432
|
+
"from": "agents/**/*.md",
|
|
433
|
+
"to": ".claude/agents/**/*.md",
|
|
434
|
+
"map": [
|
|
435
|
+
// 1. Inject filename as name
|
|
436
|
+
{ "$set": { "name": "$$filename" } },
|
|
437
|
+
|
|
438
|
+
// 2. Simplify model ID
|
|
439
|
+
{
|
|
440
|
+
"$pipeline": {
|
|
441
|
+
"field": "model",
|
|
442
|
+
"operations": [
|
|
443
|
+
{ "$replace": { "pattern": "^anthropic/", "with": "" } },
|
|
444
|
+
{ "$replace": { "pattern": "(-[0-9]+)\\.([0-9]+)", "with": "$1-$2", "flags": "g" } }
|
|
445
|
+
]
|
|
446
|
+
}
|
|
447
|
+
},
|
|
448
|
+
|
|
449
|
+
// 3. Transform tools object to CSV
|
|
450
|
+
{
|
|
451
|
+
"$pipeline": {
|
|
452
|
+
"field": "tools",
|
|
453
|
+
"operations": [
|
|
454
|
+
{ "$filter": { "match": { "value": true } } },
|
|
455
|
+
{ "$objectToArray": { "extract": "keys" } },
|
|
456
|
+
{ "$map": { "each": "capitalize" } },
|
|
457
|
+
{ "$reduce": { "type": "join", "separator": ", " } }
|
|
458
|
+
]
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
|
|
462
|
+
// 4. Transform permission to mode
|
|
463
|
+
{
|
|
464
|
+
"$copy": {
|
|
465
|
+
"from": "permission",
|
|
466
|
+
"to": "permissionMode",
|
|
467
|
+
"transform": {
|
|
468
|
+
"cases": [
|
|
469
|
+
{ "pattern": { "edit": "deny", "bash": "deny" }, "value": "plan" }
|
|
470
|
+
],
|
|
471
|
+
"default": "default"
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
|
|
476
|
+
// 5. Remove original permission field
|
|
477
|
+
{ "$unset": "permission" }
|
|
478
|
+
]
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
**Input:**
|
|
483
|
+
```yaml
|
|
484
|
+
---
|
|
485
|
+
model: anthropic/claude-sonnet-4-20250514
|
|
486
|
+
tools:
|
|
487
|
+
write: false
|
|
488
|
+
bash: true
|
|
489
|
+
read: true
|
|
490
|
+
permission:
|
|
491
|
+
edit: deny
|
|
492
|
+
bash: deny
|
|
493
|
+
---
|
|
494
|
+
# Code Reviewer
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
**Output:**
|
|
498
|
+
```yaml
|
|
499
|
+
---
|
|
500
|
+
name: code-reviewer
|
|
501
|
+
model: claude-sonnet-4-20250514
|
|
502
|
+
tools: Bash, Read
|
|
503
|
+
permissionMode: plan
|
|
504
|
+
---
|
|
505
|
+
# Code Reviewer
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
## `$pipeline` Operation Details
|
|
509
|
+
|
|
510
|
+
### `$filter` - Filter Object Entries
|
|
511
|
+
|
|
512
|
+
```jsonc
|
|
513
|
+
// Filter by value
|
|
514
|
+
{ "$filter": { "match": { "value": true } } }
|
|
515
|
+
|
|
516
|
+
// Filter by key
|
|
517
|
+
{ "$filter": { "match": { "key": "enabled" } } }
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
**MongoDB equivalent:** `$filter` operator
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
### `$objectToArray` - Convert Object to Array
|
|
525
|
+
|
|
526
|
+
```jsonc
|
|
527
|
+
// Extract keys only
|
|
528
|
+
{ "$objectToArray": { "extract": "keys" } }
|
|
529
|
+
// { a: 1, b: 2 } → ["a", "b"]
|
|
530
|
+
|
|
531
|
+
// Extract values only
|
|
532
|
+
{ "$objectToArray": { "extract": "values" } }
|
|
533
|
+
// { a: 1, b: 2 } → [1, 2]
|
|
534
|
+
|
|
535
|
+
// Extract entries (default)
|
|
536
|
+
{ "$objectToArray": { "extract": "entries" } }
|
|
537
|
+
// { a: 1, b: 2 } → [["a", 1], ["b", 2]]
|
|
538
|
+
|
|
539
|
+
// Shorthand for entries
|
|
540
|
+
{ "$objectToArray": true }
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
**MongoDB equivalent:** `$objectToArray` (exact match for entries mode)
|
|
544
|
+
|
|
545
|
+
---
|
|
546
|
+
|
|
547
|
+
### `$arrayToObject` - Convert Array to Object
|
|
548
|
+
|
|
549
|
+
```jsonc
|
|
550
|
+
// Array of strings to object with fixed value
|
|
551
|
+
{ "$arrayToObject": { "value": true } }
|
|
552
|
+
// ["bash", "read"] → { bash: true, read: true }
|
|
553
|
+
|
|
554
|
+
// With context variable
|
|
555
|
+
{ "$arrayToObject": { "value": "$$filename" } }
|
|
556
|
+
// ["tool1", "tool2"] → { tool1: "code-reviewer", tool2: "code-reviewer" }
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
**MongoDB equivalent:** `$arrayToObject` (similar, but MongoDB uses entries format)
|
|
560
|
+
|
|
561
|
+
---
|
|
562
|
+
|
|
563
|
+
### `$map` - Transform Array Elements
|
|
564
|
+
|
|
565
|
+
```jsonc
|
|
566
|
+
{ "$map": { "each": "capitalize" } }
|
|
567
|
+
// ["hello", "world"] → ["Hello", "World"]
|
|
568
|
+
|
|
569
|
+
{ "$map": { "each": "uppercase" } }
|
|
570
|
+
// ["hello", "world"] → ["HELLO", "WORLD"]
|
|
571
|
+
|
|
572
|
+
{ "$map": { "each": "lowercase" } }
|
|
573
|
+
// ["HELLO", "WORLD"] → ["hello", "world"]
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
**MongoDB equivalent:** `$map` (similar structure)
|
|
577
|
+
|
|
578
|
+
---
|
|
579
|
+
|
|
580
|
+
### `$reduce` - Reduce Array to Single Value
|
|
581
|
+
|
|
582
|
+
```jsonc
|
|
583
|
+
// Join array to string
|
|
584
|
+
{ "$reduce": { "type": "join", "separator": ", " } }
|
|
585
|
+
// ["bash", "read"] → "bash, read"
|
|
586
|
+
|
|
587
|
+
// Split string to array
|
|
588
|
+
{ "$reduce": { "type": "split", "separator": ", " } }
|
|
589
|
+
// "bash, read" → ["bash", "read"]
|
|
590
|
+
|
|
591
|
+
// Sum numbers
|
|
592
|
+
{ "$reduce": { "type": "sum" } }
|
|
593
|
+
// [1, 2, 3] → 6
|
|
594
|
+
|
|
595
|
+
// Count elements
|
|
596
|
+
{ "$reduce": { "type": "count" } }
|
|
597
|
+
// ["a", "b", "c"] → 3
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
**MongoDB equivalent:** `$reduce` (inspired by MongoDB's `$reduce`, but simplified)
|
|
601
|
+
|
|
602
|
+
---
|
|
603
|
+
|
|
604
|
+
### `$replace` - String Replacement with Regex
|
|
605
|
+
|
|
606
|
+
```jsonc
|
|
607
|
+
// Simple replacement
|
|
608
|
+
{ "$replace": { "pattern": "^anthropic/", "with": "" } }
|
|
609
|
+
// "anthropic/claude-sonnet" → "claude-sonnet"
|
|
610
|
+
|
|
611
|
+
// With capture groups
|
|
612
|
+
{ "$replace": { "pattern": "(-[0-9]+)\\.([0-9]+)", "with": "$1-$2", "flags": "g" } }
|
|
613
|
+
// "claude-4.5" → "claude-4-5"
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
**MongoDB equivalent:** `$replaceOne` / `$replaceAll`
|
|
617
|
+
|
|
618
|
+
## Validation
|
|
619
|
+
|
|
620
|
+
Pipelines are validated against `schemas/map-pipeline-v1.json` before execution.
|
|
621
|
+
|
|
622
|
+
**Valid:**
|
|
623
|
+
```jsonc
|
|
624
|
+
[
|
|
625
|
+
{ "$set": { "name": "$$filename" } },
|
|
626
|
+
{ "$rename": { "old": "new" } }
|
|
627
|
+
]
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
**Invalid - multiple operations per object:**
|
|
631
|
+
```jsonc
|
|
632
|
+
[
|
|
633
|
+
{
|
|
634
|
+
"$set": { "name": "$$filename" },
|
|
635
|
+
"$rename": { "old": "new" } // Error!
|
|
636
|
+
}
|
|
637
|
+
]
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
**Invalid - unknown operation:**
|
|
641
|
+
```jsonc
|
|
642
|
+
[
|
|
643
|
+
{ "$unknown": { "field": "value" } } // Error!
|
|
644
|
+
]
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
## Testing
|
|
648
|
+
|
|
649
|
+
Comprehensive test suite: `tests/flows/map-pipeline.test.ts`
|
|
650
|
+
|
|
651
|
+
**Run tests:**
|
|
652
|
+
```bash
|
|
653
|
+
npm test -- map-pipeline
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
**Test coverage:**
|
|
657
|
+
- All 6 operations
|
|
658
|
+
- Context variable resolution
|
|
659
|
+
- Nested field access
|
|
660
|
+
- Wildcard patterns
|
|
661
|
+
- Pattern matching
|
|
662
|
+
- Empty result handling
|
|
663
|
+
- Error cases
|
|
664
|
+
- Integration with flow execution
|
|
665
|
+
|
|
666
|
+
## Best Practices
|
|
667
|
+
|
|
668
|
+
### 1. Keep Pipelines Simple
|
|
669
|
+
|
|
670
|
+
```jsonc
|
|
671
|
+
// Good
|
|
672
|
+
{ "$rename": { "mcp": "mcpServers" } }
|
|
673
|
+
|
|
674
|
+
// Avoid unnecessary complexity
|
|
675
|
+
[
|
|
676
|
+
{ "$copy": { "from": "mcp", "to": "temp" } },
|
|
677
|
+
{ "$unset": "mcp" },
|
|
678
|
+
{ "$rename": { "temp": "mcpServers" } }
|
|
679
|
+
]
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
### 2. Order Operations Logically
|
|
683
|
+
|
|
684
|
+
```jsonc
|
|
685
|
+
[
|
|
686
|
+
{ "$set": { ... } }, // 1. Add fields
|
|
687
|
+
{ "$switch": { ... } }, // 2. Transform values
|
|
688
|
+
{ "$pipeline": { ... } }, // 3. Complex transforms
|
|
689
|
+
{ "$copy": { ... } }, // 4. Derive fields
|
|
690
|
+
{ "$unset": [...] } // 5. Cleanup
|
|
691
|
+
]
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### 3. Leverage Context Variables
|
|
695
|
+
|
|
696
|
+
```jsonc
|
|
697
|
+
{ "$set": {
|
|
698
|
+
"name": "$$filename",
|
|
699
|
+
"source": "$$path",
|
|
700
|
+
"category": "$$dirname"
|
|
701
|
+
}}
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### 4. Document Complex Pipelines
|
|
705
|
+
|
|
706
|
+
```jsonc
|
|
707
|
+
{
|
|
708
|
+
"map": [
|
|
709
|
+
// Extract filename as agent name
|
|
710
|
+
{ "$set": { "name": "$$filename" } },
|
|
711
|
+
|
|
712
|
+
// Convert full model ID to short name for Claude compatibility
|
|
713
|
+
{
|
|
714
|
+
"$pipeline": {
|
|
715
|
+
"field": "model",
|
|
716
|
+
"operations": [
|
|
717
|
+
{ "$replace": { "pattern": "^anthropic/", "with": "" } }
|
|
718
|
+
]
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
]
|
|
722
|
+
}
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
### 5. Test Incrementally
|
|
726
|
+
|
|
727
|
+
```bash
|
|
728
|
+
# Preview transformations
|
|
729
|
+
opkg install @user/package --dry-run
|
|
730
|
+
|
|
731
|
+
# Verify specific file
|
|
732
|
+
cat .claude/agents/code-reviewer.md
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
## Performance
|
|
736
|
+
|
|
737
|
+
**Optimized execution:**
|
|
738
|
+
- Document cloned once at start (prevents mutations)
|
|
739
|
+
- All operations execute in-memory (no I/O)
|
|
740
|
+
- Operations are O(1) to O(n) where n = number of fields
|
|
741
|
+
- Pattern matching uses optimized glob library
|
|
742
|
+
- Pipeline operations are O(operations × elements)
|
|
743
|
+
|
|
744
|
+
**Recommendations:**
|
|
745
|
+
- Keep pipelines under 10 operations
|
|
746
|
+
- Combine multiple `$set` operations into one
|
|
747
|
+
- Use `$copy` with transform instead of separate operations
|
|
748
|
+
|
|
749
|
+
## Related Documentation
|
|
750
|
+
|
|
751
|
+
- **Breaking Changes:** `BREAKING_CHANGES.md` - MongoDB alignment migration
|
|
752
|
+
- **MongoDB Alignment:** `MONGODB_ALIGNMENT.md` - Complete migration guide
|
|
753
|
+
- **Examples:** `MONGODB_ALIGNMENT_EXAMPLE.md` - Step-by-step examples
|
|
754
|
+
- **Type Definitions:** `src/core/flows/map-pipeline/types.ts` - TypeScript types
|
|
755
|
+
- **JSON Schema:** `schemas/map-pipeline-v1.json` - Validation schema
|
|
756
|
+
- **Tests:** `tests/flows/map-pipeline.test.ts` - Test suite
|
|
757
|
+
- **Flow Documentation:** `specs/platforms/flows.md` - Flow system overview
|
|
758
|
+
|
|
759
|
+
## MongoDB Alignment (Breaking Change)
|
|
760
|
+
|
|
761
|
+
**Date:** January 9, 2026
|
|
762
|
+
|
|
763
|
+
The pipeline syntax has been updated to align with MongoDB aggregation conventions:
|
|
764
|
+
|
|
765
|
+
### What Changed
|
|
766
|
+
|
|
767
|
+
1. **`$transform` renamed to `$pipeline`**
|
|
768
|
+
2. **`steps` renamed to `operations`**
|
|
769
|
+
3. **All sub-operations now use `$` prefix:**
|
|
770
|
+
- `filter` → `$filter`
|
|
771
|
+
- `keys`/`values`/`entries` → `$objectToArray`
|
|
772
|
+
- `map` → `$map`
|
|
773
|
+
- `join`/`split` → `$reduce`
|
|
774
|
+
- `arrayToObject` → `$arrayToObject`
|
|
775
|
+
- `replace` → `$replace`
|
|
776
|
+
|
|
777
|
+
### Migration Required
|
|
778
|
+
|
|
779
|
+
See `BREAKING_CHANGES.md` for complete migration guide.
|
|
780
|
+
|
|
781
|
+
## Summary
|
|
782
|
+
|
|
783
|
+
The Map Pipeline provides a powerful, MongoDB-aligned transformation system for document-level operations:
|
|
784
|
+
|
|
785
|
+
✓ **7 core operations:** set, rename, unset, switch, pipeline, copy, pipe
|
|
786
|
+
✓ **Context-aware:** Access file metadata with `$$` variables
|
|
787
|
+
✓ **Sequential execution:** Predictable, composable transformations
|
|
788
|
+
✓ **Type-safe:** Full TypeScript support
|
|
789
|
+
✓ **Validated:** JSON Schema enforcement
|
|
790
|
+
✓ **Tested:** Comprehensive test coverage
|
|
791
|
+
✓ **Performant:** In-memory operations with minimal overhead
|
|
792
|
+
✓ **MongoDB-aligned:** Familiar operators for MongoDB developers
|
|
793
|
+
✓ **Transform integration:** `$pipe` bridges map pipeline with transform registry
|
|
794
|
+
|
|
795
|
+
For complete examples and usage patterns, see the related documentation above.
|
|
796
|
+
|
|
797
|
+
---
|
|
798
|
+
|
|
799
|
+
**Map Pipeline v1.0** - Implemented in commit `e464927d2f5d2480c439a83c5cfc2e04053ac22d`
|
|
800
|
+
**MongoDB Alignment** - Updated January 9, 2026 (Breaking Change)
|
|
801
|
+
**`$pipe` Operation** - Added January 2026
|