opkg 0.5.0 → 0.6.1
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 +82 -21
- package/dist/commands/add.js +11 -276
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/duplicate.js +5 -2
- package/dist/commands/duplicate.js.map +1 -1
- package/dist/commands/init.js +76 -145
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install.js +30 -671
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/list.js +9 -3
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/login.js +58 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.js +28 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/pack.js +10 -137
- package/dist/commands/pack.js.map +1 -1
- package/dist/commands/pull.js +5 -299
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/push.js +5 -239
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/save.js +29 -168
- package/dist/commands/save.js.map +1 -1
- package/dist/commands/show.js +18 -5
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/status.js +21 -8
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/tui.js +61 -0
- package/dist/commands/tui.js.map +1 -0
- package/dist/commands/uninstall.js +5 -5
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/constants/index.js +19 -45
- package/dist/constants/index.js.map +1 -1
- package/dist/constants/workspace.js +9 -0
- package/dist/constants/workspace.js.map +1 -0
- package/dist/core/add/add-conflict-handler.js +68 -0
- package/dist/core/add/add-conflict-handler.js.map +1 -0
- package/dist/core/add/add-pipeline.js +137 -0
- package/dist/core/add/add-pipeline.js.map +1 -0
- package/dist/core/add/package-index-updater.js +66 -36
- package/dist/core/add/package-index-updater.js.map +1 -1
- package/dist/core/add/platform-path-transformer.js +47 -0
- package/dist/core/add/platform-path-transformer.js.map +1 -0
- package/dist/core/add/source-collector.js +57 -0
- package/dist/core/add/source-collector.js.map +1 -0
- package/dist/core/api-keys.js +6 -2
- package/dist/core/api-keys.js.map +1 -1
- package/dist/core/auth.js +25 -40
- package/dist/core/auth.js.map +1 -1
- package/dist/core/config.js +11 -3
- package/dist/core/config.js.map +1 -1
- package/dist/core/dependency-resolver.js +24 -11
- package/dist/core/dependency-resolver.js.map +1 -1
- package/dist/core/device-auth.js +81 -0
- package/dist/core/device-auth.js.map +1 -0
- package/dist/core/directory.js +15 -9
- package/dist/core/directory.js.map +1 -1
- package/dist/core/discovery/file-discovery.js +55 -54
- package/dist/core/discovery/file-discovery.js.map +1 -1
- package/dist/core/discovery/platform-files-discovery.js +32 -17
- package/dist/core/discovery/platform-files-discovery.js.map +1 -1
- package/dist/core/install/bulk-install-pipeline.js +200 -0
- package/dist/core/install/bulk-install-pipeline.js.map +1 -0
- package/dist/core/install/canonical-plan.js +129 -0
- package/dist/core/install/canonical-plan.js.map +1 -0
- package/dist/core/install/download-keys.js +2 -2
- package/dist/core/install/download-keys.js.map +1 -1
- package/dist/core/install/dry-run.js +2 -2
- package/dist/core/install/dry-run.js.map +1 -1
- package/dist/core/install/index.js +3 -0
- package/dist/core/install/index.js.map +1 -0
- package/dist/core/install/install-errors.js +41 -0
- package/dist/core/install/install-errors.js.map +1 -0
- package/dist/core/install/install-flow.js +8 -9
- package/dist/core/install/install-flow.js.map +1 -1
- package/dist/core/install/install-pipeline.js +296 -0
- package/dist/core/install/install-pipeline.js.map +1 -0
- package/dist/core/install/install-reporting.js +99 -0
- package/dist/core/install/install-reporting.js.map +1 -0
- package/dist/core/install/platform-resolution.js +6 -6
- package/dist/core/install/platform-resolution.js.map +1 -1
- package/dist/core/install/remote-flow.js +84 -7
- package/dist/core/install/remote-flow.js.map +1 -1
- package/dist/core/install/version-selection.js +25 -8
- package/dist/core/install/version-selection.js.map +1 -1
- package/dist/core/openpackage.js +22 -14
- package/dist/core/openpackage.js.map +1 -1
- package/dist/core/package-context.js +246 -0
- package/dist/core/package-context.js.map +1 -0
- package/dist/core/package.js +73 -9
- package/dist/core/package.js.map +1 -1
- package/dist/core/platforms.js +126 -217
- package/dist/core/platforms.js.map +1 -1
- package/dist/core/profiles.js +60 -3
- package/dist/core/profiles.js.map +1 -1
- package/dist/core/pull/pull-errors.js +62 -0
- package/dist/core/pull/pull-errors.js.map +1 -0
- package/dist/core/pull/pull-options.js +2 -0
- package/dist/core/pull/pull-options.js.map +1 -0
- package/dist/core/pull/pull-output.js +50 -0
- package/dist/core/pull/pull-output.js.map +1 -0
- package/dist/core/pull/pull-pipeline.js +141 -0
- package/dist/core/pull/pull-pipeline.js.map +1 -0
- package/dist/core/pull/pull-strategies.js +103 -0
- package/dist/core/pull/pull-strategies.js.map +1 -0
- package/dist/core/pull/pull-types.js +2 -0
- package/dist/core/pull/pull-types.js.map +1 -0
- package/dist/core/push/push-context.js +95 -0
- package/dist/core/push/push-context.js.map +1 -0
- package/dist/core/push/push-errors.js +133 -0
- package/dist/core/push/push-errors.js.map +1 -0
- package/dist/core/push/push-output.js +44 -0
- package/dist/core/push/push-output.js.map +1 -0
- package/dist/core/push/push-pipeline.js +74 -0
- package/dist/core/push/push-pipeline.js.map +1 -0
- package/dist/core/push/push-single-file.js +56 -0
- package/dist/core/push/push-single-file.js.map +1 -0
- package/dist/core/push/push-types.js +2 -0
- package/dist/core/push/push-types.js.map +1 -0
- package/dist/core/push/push-upload.js +68 -0
- package/dist/core/push/push-upload.js.map +1 -0
- package/dist/core/registry/registry-rename.js +2 -1
- package/dist/core/registry/registry-rename.js.map +1 -1
- package/dist/core/registry.js +14 -5
- package/dist/core/registry.js.map +1 -1
- package/dist/core/remote-pull.js +165 -36
- package/dist/core/remote-pull.js.map +1 -1
- package/dist/core/save/constants.js +4 -0
- package/dist/core/save/constants.js.map +1 -1
- package/dist/core/save/name-resolution.js +31 -0
- package/dist/core/save/name-resolution.js.map +1 -0
- package/dist/core/save/package-detection.js +147 -0
- package/dist/core/save/package-detection.js.map +1 -0
- package/dist/core/save/package-saver.js +82 -43
- package/dist/core/save/package-saver.js.map +1 -1
- package/dist/core/save/package-yml-generator.js +51 -71
- package/dist/core/save/package-yml-generator.js.map +1 -1
- package/dist/core/save/root-save-candidates.js.map +1 -1
- package/dist/core/save/save-candidate-loader.js +89 -0
- package/dist/core/save/save-candidate-loader.js.map +1 -0
- package/dist/core/save/save-conflict-resolution.js +72 -410
- package/dist/core/save/save-conflict-resolution.js.map +1 -1
- package/dist/core/save/save-conflict-resolver.js +277 -0
- package/dist/core/save/save-conflict-resolver.js.map +1 -0
- package/dist/core/save/save-pipeline.js +162 -0
- package/dist/core/save/save-pipeline.js.map +1 -0
- package/dist/core/save/save-single-file.js +124 -0
- package/dist/core/save/save-single-file.js.map +1 -0
- package/dist/core/save/save-types.js +2 -0
- package/dist/core/save/save-types.js.map +1 -0
- package/dist/core/save/save-yml-resolution.js +77 -39
- package/dist/core/save/save-yml-resolution.js.map +1 -1
- package/dist/core/save/workspace-rename.js +6 -6
- package/dist/core/save/workspace-rename.js.map +1 -1
- package/dist/core/scoping/package-scoping.js +14 -2
- package/dist/core/scoping/package-scoping.js.map +1 -1
- package/dist/core/status/status-file-discovery.js +12 -30
- package/dist/core/status/status-file-discovery.js.map +1 -1
- package/dist/core/sync/platform-sync.js +7 -4
- package/dist/core/sync/platform-sync.js.map +1 -1
- package/dist/core/sync/root-files-sync.js +59 -1
- package/dist/core/sync/root-files-sync.js.map +1 -1
- package/dist/core/token-store.js +73 -0
- package/dist/core/token-store.js.map +1 -0
- package/dist/core/uninstall/uninstall-file-discovery.js +1 -2
- package/dist/core/uninstall/uninstall-file-discovery.js.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/tui/app.js +95 -0
- package/dist/tui/app.js.map +1 -0
- package/dist/tui/components/package-list.js +73 -0
- package/dist/tui/components/package-list.js.map +1 -0
- package/dist/tui/controller.js +365 -0
- package/dist/tui/controller.js.map +1 -0
- package/dist/tui/index.js +12 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/services/file-index.js +64 -0
- package/dist/tui/services/file-index.js.map +1 -0
- package/dist/tui/services/packages.js +18 -0
- package/dist/tui/services/packages.js.map +1 -0
- package/dist/tui/services/save.js +21 -0
- package/dist/tui/services/save.js.map +1 -0
- package/dist/tui/state/app-state.js +15 -0
- package/dist/tui/state/app-state.js.map +1 -0
- package/dist/tui/state.js +17 -0
- package/dist/tui/state.js.map +1 -0
- package/dist/tui/types.js +2 -0
- package/dist/tui/types.js.map +1 -0
- package/dist/tui/views/add-file-modal.js +129 -0
- package/dist/tui/views/add-file-modal.js.map +1 -0
- package/dist/tui/views/file-preview.js +44 -0
- package/dist/tui/views/file-preview.js.map +1 -0
- package/dist/tui/views/list-packages.js +73 -0
- package/dist/tui/views/list-packages.js.map +1 -0
- package/dist/tui/views/main-menu.js +29 -0
- package/dist/tui/views/main-menu.js.map +1 -0
- package/dist/tui/views/manage-view.js +81 -0
- package/dist/tui/views/manage-view.js.map +1 -0
- package/dist/tui/views/package-hub.js +120 -0
- package/dist/tui/views/package-hub.js.map +1 -0
- package/dist/tui/views/placeholder.js +24 -0
- package/dist/tui/views/placeholder.js.map +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/utils/bun-bootstrap.js +72 -0
- package/dist/utils/bun-bootstrap.js.map +1 -0
- package/dist/utils/file-processing.js +5 -58
- package/dist/utils/file-processing.js.map +1 -1
- package/dist/utils/formatters.js +3 -1
- package/dist/utils/formatters.js.map +1 -1
- package/dist/utils/http-client.js +27 -5
- package/dist/utils/http-client.js.map +1 -1
- package/dist/utils/index-based-installer.js +40 -35
- package/dist/utils/index-based-installer.js.map +1 -1
- package/dist/utils/install-file-discovery.js +18 -24
- package/dist/utils/install-file-discovery.js.map +1 -1
- package/dist/utils/install-orchestrator.js +21 -21
- package/dist/utils/install-orchestrator.js.map +1 -1
- package/dist/utils/jsonc.js +44 -0
- package/dist/utils/jsonc.js.map +1 -0
- package/dist/utils/manifest-paths.js +27 -0
- package/dist/utils/manifest-paths.js.map +1 -0
- package/dist/utils/package-copy.js +199 -0
- package/dist/utils/package-copy.js.map +1 -0
- package/dist/utils/package-filters.js +125 -0
- package/dist/utils/package-filters.js.map +1 -0
- package/dist/utils/package-index-yml.js +15 -10
- package/dist/utils/package-index-yml.js.map +1 -1
- package/dist/utils/package-installation.js +4 -113
- package/dist/utils/package-installation.js.map +1 -1
- package/dist/utils/package-local-files.js +2 -35
- package/dist/utils/package-local-files.js.map +1 -1
- package/dist/utils/package-management.js +191 -75
- package/dist/utils/package-management.js.map +1 -1
- package/dist/utils/package-merge.js +48 -0
- package/dist/utils/package-merge.js.map +1 -0
- package/dist/utils/package-name.js +29 -0
- package/dist/utils/package-name.js.map +1 -1
- package/dist/utils/package-versioning.js +16 -4
- package/dist/utils/package-versioning.js.map +1 -1
- package/dist/utils/package-yml.js +41 -12
- package/dist/utils/package-yml.js.map +1 -1
- package/dist/utils/path-normalization.js +8 -53
- package/dist/utils/path-normalization.js.map +1 -1
- package/dist/utils/paths.js +17 -9
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/platform-file.js +16 -59
- package/dist/utils/platform-file.js.map +1 -1
- package/dist/utils/platform-mapper.js +29 -41
- package/dist/utils/platform-mapper.js.map +1 -1
- package/dist/utils/platform-specific-paths.js.map +1 -1
- package/dist/utils/platform-utils.js +28 -139
- package/dist/utils/platform-utils.js.map +1 -1
- package/dist/utils/platform-yaml-merge.js +13 -6
- package/dist/utils/platform-yaml-merge.js.map +1 -1
- package/dist/utils/prompts.js +0 -31
- package/dist/utils/prompts.js.map +1 -1
- package/dist/utils/registry-entry-filter.js +38 -24
- package/dist/utils/registry-entry-filter.js.map +1 -1
- package/dist/utils/registry-paths.js +48 -0
- package/dist/utils/registry-paths.js.map +1 -0
- package/dist/utils/root-file-installer.js +19 -0
- package/dist/utils/root-file-installer.js.map +1 -1
- package/dist/utils/root-file-registry.js.map +1 -1
- package/dist/utils/tarball.js +6 -2
- package/dist/utils/tarball.js.map +1 -1
- package/dist/utils/version-ranges.js +11 -8
- package/dist/utils/version-ranges.js.map +1 -1
- package/package.json +3 -2
- package/platforms.jsonc +178 -0
- package/specs/auth/auth-device-flow.md +70 -0
- package/specs/install/install-behavior.md +30 -0
- package/specs/install/package-yml-canonical.md +21 -1
- package/specs/install/version-resolution.md +9 -7
- package/specs/login/login-device-flow.md +70 -0
- package/specs/package/README.md +60 -0
- package/specs/package/nested-packages-and-parent-packages.md +79 -0
- package/specs/package/package-index-yml.md +171 -0
- package/specs/package/package-root-layout.md +78 -0
- package/specs/package/registry-payload-and-copy.md +77 -0
- package/specs/package/universal-content.md +144 -0
- package/specs/platforms.md +193 -0
- package/specs/push/push-behavior.md +38 -10
- package/specs/push/push-errors-and-hints.md +19 -6
- package/specs/push/push-remote-upload.md +3 -0
- package/specs/push/push-scoping.md +14 -22
- package/specs/push/push-version-selection.md +18 -16
- package/specs/save/README.md +40 -0
- package/specs/save/save-conflict-resolution.md +146 -0
- package/specs/save/save-file-discovery.md +101 -0
- package/specs/save/save-frontmatter-overrides.md +81 -0
- package/specs/save/save-modes-inputs.md +55 -0
- package/specs/save/save-naming-scoping.md +93 -0
- package/specs/save/save-package-detection.md +60 -0
- package/specs/save/save-registry-sync.md +126 -0
- package/specs/save-pack.md +1 -0
- package/dist/commands/release.js +0 -33
- package/dist/commands/release.js.map +0 -1
- package/dist/commands/tag.js +0 -311
- package/dist/commands/tag.js.map +0 -1
- package/dist/commands/update.js +0 -30
- package/dist/commands/update.js.map +0 -1
- package/dist/core/add/formula-index-updater.js +0 -290
- package/dist/core/add/formula-index-updater.js.map +0 -1
- package/dist/core/discovery/ai-files-discovery.js +0 -2
- package/dist/core/discovery/ai-files-discovery.js.map +0 -1
- package/dist/core/discovery/formula-files-discovery.js +0 -14
- package/dist/core/discovery/formula-files-discovery.js.map +0 -1
- package/dist/core/discovery/index-files-discovery.js +0 -91
- package/dist/core/discovery/index-files-discovery.js.map +0 -1
- package/dist/core/discovery/md-files-discovery.js +0 -82
- package/dist/core/discovery/md-files-discovery.js.map +0 -1
- package/dist/core/discovery/package-files-discovery.js +0 -14
- package/dist/core/discovery/package-files-discovery.js.map +0 -1
- package/dist/core/discovery/platform-discovery.js +0 -84
- package/dist/core/discovery/platform-discovery.js.map +0 -1
- package/dist/core/discovery/root-files-discovery.js +0 -2
- package/dist/core/discovery/root-files-discovery.js.map +0 -1
- package/dist/core/formula.js +0 -170
- package/dist/core/formula.js.map +0 -1
- package/dist/core/git-registry.js +0 -46
- package/dist/core/git-registry.js.map +0 -1
- package/dist/core/groundzero.js +0 -277
- package/dist/core/groundzero.js.map +0 -1
- package/dist/core/install/scenario.js +0 -11
- package/dist/core/install/scenario.js.map +0 -1
- package/dist/core/package-sync.js +0 -219
- package/dist/core/package-sync.js.map +0 -1
- package/dist/core/save/formula-file-generator.js +0 -167
- package/dist/core/save/formula-file-generator.js.map +0 -1
- package/dist/core/save/formula-saver.js +0 -52
- package/dist/core/save/formula-saver.js.map +0 -1
- package/dist/core/save/formula-yml-generator.js +0 -89
- package/dist/core/save/formula-yml-generator.js.map +0 -1
- package/dist/core/save/formula-yml-versioning.js +0 -108
- package/dist/core/save/formula-yml-versioning.js.map +0 -1
- package/dist/core/save/generic-file-sync.js +0 -38
- package/dist/core/save/generic-file-sync.js.map +0 -1
- package/dist/core/save/md-files-sync.js +0 -33
- package/dist/core/save/md-files-sync.js.map +0 -1
- package/dist/core/save/package-yml-versioning.js +0 -108
- package/dist/core/save/package-yml-versioning.js.map +0 -1
- package/dist/core/save/platform-sync.js +0 -95
- package/dist/core/save/platform-sync.js.map +0 -1
- package/dist/core/save/root-files-sync.js +0 -140
- package/dist/core/save/root-files-sync.js.map +0 -1
- package/dist/core/save/save-candidate-types.js +0 -2
- package/dist/core/save/save-candidate-types.js.map +0 -1
- package/dist/core/save/save-conflict-types.js +0 -2
- package/dist/core/save/save-conflict-types.js.map +0 -1
- package/dist/core/save/save-file-discovery.js +0 -5
- package/dist/core/save/save-file-discovery.js.map +0 -1
- package/dist/core/status-file-discovery.js +0 -175
- package/dist/core/status-file-discovery.js.map +0 -1
- package/dist/utils/discovery/file-processing.js +0 -156
- package/dist/utils/discovery/file-processing.js.map +0 -1
- package/dist/utils/discovery/formula-discovery.js +0 -211
- package/dist/utils/discovery/formula-discovery.js.map +0 -1
- package/dist/utils/discovery/platform-discovery.js +0 -2
- package/dist/utils/discovery/platform-discovery.js.map +0 -1
- package/dist/utils/formula-discovery.js +0 -102
- package/dist/utils/formula-discovery.js.map +0 -1
- package/dist/utils/formula-index-yml.js +0 -122
- package/dist/utils/formula-index-yml.js.map +0 -1
- package/dist/utils/formula-installation.js +0 -110
- package/dist/utils/formula-installation.js.map +0 -1
- package/dist/utils/formula-local-files.js +0 -38
- package/dist/utils/formula-local-files.js.map +0 -1
- package/dist/utils/formula-management.js +0 -191
- package/dist/utils/formula-management.js.map +0 -1
- package/dist/utils/formula-name.js +0 -97
- package/dist/utils/formula-name.js.map +0 -1
- package/dist/utils/formula-versioning.js +0 -109
- package/dist/utils/formula-versioning.js.map +0 -1
- package/dist/utils/formula-yml.js +0 -82
- package/dist/utils/formula-yml.js.map +0 -1
- package/dist/utils/git.js +0 -54
- package/dist/utils/git.js.map +0 -1
- package/dist/utils/id-based-discovery.js +0 -126
- package/dist/utils/id-based-discovery.js.map +0 -1
- package/dist/utils/id-based-installer.js +0 -249
- package/dist/utils/id-based-installer.js.map +0 -1
- package/dist/utils/index-yml-based-installer.js +0 -375
- package/dist/utils/index-yml-based-installer.js.map +0 -1
- package/dist/utils/index-yml.js +0 -124
- package/dist/utils/index-yml.js.map +0 -1
- package/dist/utils/md-frontmatter.js +0 -3
- package/dist/utils/md-frontmatter.js.map +0 -1
- package/dist/utils/package-link-yml.js +0 -92
- package/dist/utils/package-link-yml.js.map +0 -1
- package/dist/utils/platform-discovery.js +0 -2
- package/dist/utils/platform-discovery.js.map +0 -1
- package/dist/utils/platform-frontmatter-split.js +0 -15
- package/dist/utils/platform-frontmatter-split.js.map +0 -1
- package/dist/utils/timestamp-encoder.js +0 -13
- package/dist/utils/timestamp-encoder.js.map +0 -1
- package/dist/utils/wip-versioning.js +0 -24
- package/dist/utils/wip-versioning.js.map +0 -1
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
### Package Index File (`package.index.yml`)
|
|
2
|
+
|
|
3
|
+
The `package.index.yml` file tracks the mapping between package files and their **actually installed** workspace locations.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
#### Location
|
|
8
|
+
|
|
9
|
+
- **Root package**: `cwd/.openpackage/package.index.yml`
|
|
10
|
+
- **Nested package**: `cwd/.openpackage/packages/<name>/.openpackage/package.index.yml`
|
|
11
|
+
|
|
12
|
+
> **Note**: `package.index.yml` is **never** included in the registry payload. It's workspace-local metadata.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
#### Excluded Content
|
|
17
|
+
|
|
18
|
+
The following files are **never** included in the index, even though they may exist in the package:
|
|
19
|
+
|
|
20
|
+
| File | Reason |
|
|
21
|
+
|------|--------|
|
|
22
|
+
| `package.yml` | Package manifest; not synced to workspace |
|
|
23
|
+
| `.openpackage/package.yml` | Same as above (path variant) |
|
|
24
|
+
| `package.index.yml` | Index file itself; workspace-local metadata |
|
|
25
|
+
|
|
26
|
+
The index only contains entries for content that is **actually synced** to workspace locations.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
#### Structure
|
|
31
|
+
|
|
32
|
+
```yaml
|
|
33
|
+
# This file is managed by OpenPackage. Do not edit manually.
|
|
34
|
+
|
|
35
|
+
workspace:
|
|
36
|
+
hash: <workspace-hash>
|
|
37
|
+
version: <installed-version>
|
|
38
|
+
files:
|
|
39
|
+
<registry-key>:
|
|
40
|
+
- <installed-path>
|
|
41
|
+
- <installed-path>
|
|
42
|
+
<registry-key>:
|
|
43
|
+
- <installed-path>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
#### Registry Keys
|
|
49
|
+
|
|
50
|
+
Registry keys are **relative to the package root**:
|
|
51
|
+
|
|
52
|
+
| Content Type | Key Format | Example |
|
|
53
|
+
|--------------|------------|---------|
|
|
54
|
+
| Universal content | `.openpackage/<subdir>/<file>` | `.openpackage/commands/test.md` |
|
|
55
|
+
| Root-level content | `<path>` | `<dir>/helper.md` |
|
|
56
|
+
| Root files | `<filename>` | `AGENTS.md` |
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
#### Values (Installed Paths)
|
|
61
|
+
|
|
62
|
+
Values are **relative to the workspace root (`cwd`)** and represent **paths that actually exist**:
|
|
63
|
+
|
|
64
|
+
| Content Type | Value Format | Example |
|
|
65
|
+
|--------------|--------------|---------|
|
|
66
|
+
| Universal content | Platform-specific paths | `.cursor/commands/test.md`, `.opencode/commands/test.md` |
|
|
67
|
+
| Root-level content | Same as key | `ai/helper.md` |
|
|
68
|
+
|
|
69
|
+
> **Important**: The index only records paths where files **actually exist**. If a file is only installed to one platform (e.g., `.cursor/`), only that path appears in the index—not hypothetical paths for other platforms.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
#### Index Update Behavior
|
|
74
|
+
|
|
75
|
+
The index is updated differently depending on the operation:
|
|
76
|
+
|
|
77
|
+
| Operation | Behavior |
|
|
78
|
+
|-----------|----------|
|
|
79
|
+
| **Add** | Records only the source path that was used to add the file. If you add `.cursor/commands/test.md`, only that path is recorded. |
|
|
80
|
+
| **Save/Sync** | Expands the index to include all platform paths where files were actually created during sync. |
|
|
81
|
+
| **Install** | Populates the index with all platform paths where files were installed. |
|
|
82
|
+
|
|
83
|
+
This ensures the index reflects the **current state** of the workspace, not hypothetical future states.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
#### Root Package Skip Logic
|
|
88
|
+
|
|
89
|
+
For **root packages only**, when a registry key maps to the exact same value, the mapping is **skipped** because:
|
|
90
|
+
- The file is already at the correct location
|
|
91
|
+
- No installation/syncing needed
|
|
92
|
+
- Avoids redundant mappings
|
|
93
|
+
|
|
94
|
+
**Example**: For a root package, `<dir>/helper.md` → `<dir>/helper.md` is skipped.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
#### Nested Package Full Mapping
|
|
99
|
+
|
|
100
|
+
For **nested packages**, all mappings are included because:
|
|
101
|
+
- Files live inside the nested package directory
|
|
102
|
+
- Need to be mapped OUT to workspace root during install
|
|
103
|
+
|
|
104
|
+
**Example**: For nested package `foo`:
|
|
105
|
+
- File at `.openpackage/packages/foo/<dir>/helper.md`
|
|
106
|
+
- Key: `<dir>/helper.md`
|
|
107
|
+
- Value: `<dir>/helper.md` (installed at workspace root)
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
#### Complete Examples
|
|
112
|
+
|
|
113
|
+
**After `opkg add .cursor/commands/test.md`** (only source path recorded):
|
|
114
|
+
|
|
115
|
+
```yaml
|
|
116
|
+
workspace:
|
|
117
|
+
hash: abc123
|
|
118
|
+
version: 1.0.0-abc123.xyz
|
|
119
|
+
files:
|
|
120
|
+
.openpackage/commands/test.md:
|
|
121
|
+
- .cursor/commands/test.md # Only the source path that exists
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**After `opkg save`** (all synced paths recorded):
|
|
125
|
+
|
|
126
|
+
```yaml
|
|
127
|
+
workspace:
|
|
128
|
+
hash: abc123
|
|
129
|
+
version: 1.0.0-abc123.xyz
|
|
130
|
+
files:
|
|
131
|
+
.openpackage/commands/test.md:
|
|
132
|
+
- .cursor/commands/test.md # Original source
|
|
133
|
+
- .opencode/command/test.md # Synced by save
|
|
134
|
+
.openpackage/rules/auth.md:
|
|
135
|
+
- .cursor/rules/auth.mdc
|
|
136
|
+
# Note: package.yml is NOT included (it's the manifest, not synced content)
|
|
137
|
+
# Note: <dir>/helper.md is SKIPPED for root packages (maps to itself)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Nested package** (`cwd/.openpackage/packages/foo/.openpackage/package.index.yml`):
|
|
141
|
+
|
|
142
|
+
```yaml
|
|
143
|
+
workspace:
|
|
144
|
+
hash: abc123
|
|
145
|
+
version: 1.0.0
|
|
146
|
+
files:
|
|
147
|
+
.openpackage/commands/test.md:
|
|
148
|
+
- .cursor/commands/test.md
|
|
149
|
+
- .opencode/command/test.md
|
|
150
|
+
<dir>/helper.md:
|
|
151
|
+
- <dir>/helper.md
|
|
152
|
+
AGENTS.md:
|
|
153
|
+
- AGENTS.md
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
#### Add Command Examples
|
|
159
|
+
|
|
160
|
+
When adding files, the index only records the **source path that exists**:
|
|
161
|
+
|
|
162
|
+
| Command | Package | Stored At | Registry Key | Values (in index) |
|
|
163
|
+
|---------|---------|-----------|--------------|-------------------|
|
|
164
|
+
| `opkg add foo <dir>/foo.md` | Nested `foo` | `.openpackage/packages/foo/<dir>/foo.md` | `<dir>/foo.md` | `<dir>/foo.md` |
|
|
165
|
+
| `opkg add foo .cursor/test/foo.md` | Nested `foo` | `.openpackage/packages/foo/.openpackage/test/foo.md` | `.openpackage/test/foo.md` | `.cursor/test/foo.md` (only source) |
|
|
166
|
+
| `opkg add <dir>/foo.md` | Root | `.openpackage/<dir>/foo.md` | `<dir>/foo.md` | SKIPPED |
|
|
167
|
+
| `opkg add .cursor/test/foo.md` | Root | `.openpackage/test/foo.md` | `.openpackage/test/foo.md` | `.cursor/test/foo.md` (only source) |
|
|
168
|
+
|
|
169
|
+
> **Note**: After `opkg save`, the index will expand to include other platform paths (e.g., `.opencode/test/foo.md`) once those files are actually synced.
|
|
170
|
+
|
|
171
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
### Package Root Layout
|
|
2
|
+
|
|
3
|
+
Every package root directory (workspace root, nested, or registry) uses this structure:
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
<package-root>/
|
|
7
|
+
.openpackage/ # REQUIRED – package content directory
|
|
8
|
+
package.yml # REQUIRED – package manifest (marks this as a package)
|
|
9
|
+
package.index.yml # OPTIONAL – install/index metadata (never in registry payload)
|
|
10
|
+
agents/ # universal content subdirs
|
|
11
|
+
rules/
|
|
12
|
+
commands/
|
|
13
|
+
skills/
|
|
14
|
+
<custom-subdirs>/ # any additional universal content
|
|
15
|
+
<root-dirs>/ # OPTIONAL – root-level content (outside .openpackage/)
|
|
16
|
+
AGENTS.md # OPTIONAL – universal root file
|
|
17
|
+
<other-root-files> # OPTIONAL – platform-specific root files (e.g. CLAUDE.md)
|
|
18
|
+
README.md # OPTIONAL – documentation
|
|
19
|
+
packages/ # OPTIONAL – nested packages (workspace root only)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
#### Two Types of Package Content
|
|
25
|
+
|
|
26
|
+
1. **Root-level content** (outside `.openpackage/`):
|
|
27
|
+
- Any files/directories at the package root (e.g., `<dir>/foo.md`, `AGENTS.md`, `CLAUDE.md`)
|
|
28
|
+
- Live directly at the package root level, outside `.openpackage/`
|
|
29
|
+
- Stored and mapped without transformation
|
|
30
|
+
|
|
31
|
+
2. **Universal content** (inside `.openpackage/`):
|
|
32
|
+
- Platform-normalized files stored under `.openpackage/<subdir>/`
|
|
33
|
+
- Source files like `.cursor/commands/test.md` are normalized to `.openpackage/commands/test.md`
|
|
34
|
+
- Mapped to platform-specific locations during install (e.g., `.cursor/commands/`, `.opencode/commands/`)
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
#### Key Invariants
|
|
39
|
+
|
|
40
|
+
- **`.openpackage/package.yml`** marks a directory as a package root.
|
|
41
|
+
- **Universal content** (rules, agents, commands, skills, custom subdirs) lives **under `.openpackage/`**.
|
|
42
|
+
- **Root-level content** (any directories/files outside `.openpackage/`) lives **at the package root** (sibling of `.openpackage/`).
|
|
43
|
+
- **Nested packages** live under `packages/` and are treated as **independent packages**.
|
|
44
|
+
- The **same structure** applies to workspace root packages, nested packages, and registry copies.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
#### Concrete Examples
|
|
49
|
+
|
|
50
|
+
**Workspace root package** (package root = `cwd/`):
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
cwd/
|
|
54
|
+
.openpackage/
|
|
55
|
+
package.yml
|
|
56
|
+
package.index.yml
|
|
57
|
+
commands/
|
|
58
|
+
test.md
|
|
59
|
+
rules/
|
|
60
|
+
auth.md
|
|
61
|
+
<root-dir>/ # any root-level directory
|
|
62
|
+
helper.md
|
|
63
|
+
AGENTS.md
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Nested package** (package root = `cwd/.openpackage/packages/foo/`):
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
cwd/.openpackage/packages/foo/
|
|
70
|
+
.openpackage/
|
|
71
|
+
package.yml
|
|
72
|
+
package.index.yml
|
|
73
|
+
commands/
|
|
74
|
+
test.md
|
|
75
|
+
<root-dir>/ # any root-level directory
|
|
76
|
+
helper.md
|
|
77
|
+
```
|
|
78
|
+
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
### Registry Payload and 1:1 Copy
|
|
2
|
+
|
|
3
|
+
The **registry payload** for a given version is defined by two layers of rules.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
#### 1. Static Rules
|
|
8
|
+
|
|
9
|
+
**Always exclude:**
|
|
10
|
+
- `package.index.yml` (workspace-local metadata)
|
|
11
|
+
- Anything under `packages/` (nested packages are separate units)
|
|
12
|
+
|
|
13
|
+
**Always include (cannot be excluded):**
|
|
14
|
+
- `.openpackage/package.yml` (package manifest)
|
|
15
|
+
|
|
16
|
+
**Included by default (removable via manifest `exclude`):**
|
|
17
|
+
- Every platform root file declared in `platforms.jsonc` (e.g., `CLAUDE.md`, `WARP.md`, `AGENTS.md`) when it exists
|
|
18
|
+
- Any `.openpackage/<universal-subdir>/…` directory (agents, rules, commands, skills, etc.)
|
|
19
|
+
- Any root-level content (directories/files at package root, outside `.openpackage/`)
|
|
20
|
+
|
|
21
|
+
**Everything else starts excluded by default.**
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
#### 2. Manifest Filters
|
|
26
|
+
|
|
27
|
+
In `package.yml`:
|
|
28
|
+
|
|
29
|
+
- **`include`** (array): Expands the payload by listing additional glob-like patterns relative to the package root
|
|
30
|
+
- **`exclude`** (array): Removes matches after include rules are applied (but never overrides hard includes/excludes)
|
|
31
|
+
|
|
32
|
+
> **Note**: Newly created nested packages default their `package.yml` to `include: ["**"]`, so they start including all files until the author narrows the list.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
#### Save and Install Operations
|
|
37
|
+
|
|
38
|
+
**When saving:**
|
|
39
|
+
|
|
40
|
+
1. The save pipeline reads files from the package root using the rules above
|
|
41
|
+
2. Files are written **unchanged** to: `~/.openpackage/registry/<name>/<version>/...`
|
|
42
|
+
|
|
43
|
+
**When installing:**
|
|
44
|
+
|
|
45
|
+
1. The install pipeline loads `pkg.files` from the registry
|
|
46
|
+
2. Files are written 1:1 to: `cwd/.openpackage/packages/<name>/...` for local cache
|
|
47
|
+
3. Universal content is mapped to platform-specific locations in the workspace
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
#### Package Structure in Registry
|
|
52
|
+
|
|
53
|
+
Registry copies maintain the same structure as workspace packages:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
~/.openpackage/registry/<name>/<version>/
|
|
57
|
+
.openpackage/
|
|
58
|
+
package.yml # package manifest
|
|
59
|
+
commands/ # universal content
|
|
60
|
+
test.md
|
|
61
|
+
rules/
|
|
62
|
+
auth.md
|
|
63
|
+
<root-dir>/ # root-level content (any directory)
|
|
64
|
+
helper.md
|
|
65
|
+
AGENTS.md # root files
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
#### Guarantees
|
|
71
|
+
|
|
72
|
+
This system guarantees that:
|
|
73
|
+
|
|
74
|
+
- The **workspace package**, **local cache**, and **registry version directory** all share the **same tree shape**
|
|
75
|
+
- Save and install operations are **pure copies** at the package boundary, without structural rewrites
|
|
76
|
+
- Packages can be moved between locations (workspace root ↔ nested ↔ registry) without modification
|
|
77
|
+
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
### Universal Content
|
|
2
|
+
|
|
3
|
+
#### Universal Content vs. Root-Level Content
|
|
4
|
+
|
|
5
|
+
Packages contain two types of content:
|
|
6
|
+
|
|
7
|
+
| Type | Location | Description | Install Behavior |
|
|
8
|
+
|------|----------|-------------|------------------|
|
|
9
|
+
| **Universal content** | `<package-root>/.openpackage/<subdir>/` | Platform-normalized files | Mapped to platform-specific paths |
|
|
10
|
+
| **Root-level content** | `<package-root>/<path>` (outside `.openpackage/`) | Any files/dirs at package root | Copied 1:1 to same relative path |
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
#### Universal Content Layout under `.openpackage/`
|
|
15
|
+
|
|
16
|
+
Inside `.openpackage/`, each universal subdir is canonical:
|
|
17
|
+
|
|
18
|
+
```text
|
|
19
|
+
<package-root>/
|
|
20
|
+
.openpackage/
|
|
21
|
+
package.yml # package manifest
|
|
22
|
+
agents/
|
|
23
|
+
<name>.md # universal markdown
|
|
24
|
+
<name>.<platform>.md # platform-suffixed markdown (optional)
|
|
25
|
+
<name>.<platform>.yml # YAML override for frontmatter (optional)
|
|
26
|
+
rules/
|
|
27
|
+
...
|
|
28
|
+
commands/
|
|
29
|
+
...
|
|
30
|
+
skills/
|
|
31
|
+
...
|
|
32
|
+
<custom-subdirs>/ # any additional subdirs
|
|
33
|
+
...
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Definitions:**
|
|
37
|
+
|
|
38
|
+
- **Universal markdown**:
|
|
39
|
+
- Paths like `.openpackage/agents/foo.md`
|
|
40
|
+
- Contains shared body and (after save) shared frontmatter
|
|
41
|
+
|
|
42
|
+
- **Platform-suffixed markdown**:
|
|
43
|
+
- Paths like `.openpackage/agents/foo.<platform>.md`
|
|
44
|
+
- Represents platform-specific variants of a universal file
|
|
45
|
+
|
|
46
|
+
- **YAML override files**:
|
|
47
|
+
- Paths like `.openpackage/agents/foo.<platform>.yml`
|
|
48
|
+
- Contains only the **per-platform difference** in frontmatter
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
#### Root-Level Content (Outside `.openpackage/`)
|
|
53
|
+
|
|
54
|
+
Root-level content lives at the package root, **not** under `.openpackage/`:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
<package-root>/
|
|
58
|
+
.openpackage/
|
|
59
|
+
... # universal content inside
|
|
60
|
+
<root-dir>/ # any root-level directory
|
|
61
|
+
helper.md
|
|
62
|
+
prompts/
|
|
63
|
+
system.md
|
|
64
|
+
AGENTS.md # root files
|
|
65
|
+
CLAUDE.md
|
|
66
|
+
README.md
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Root-level content:
|
|
70
|
+
- Is stored and copied **without transformation**
|
|
71
|
+
- Maps to the **same relative path** in the workspace
|
|
72
|
+
- Includes any directories at the package root, platform root files (`AGENTS.md`, `CLAUDE.md`), etc.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
#### Registry Paths (Keys in `package.index.yml`)
|
|
77
|
+
|
|
78
|
+
Registry paths are **relative to the package root**:
|
|
79
|
+
|
|
80
|
+
| Content Type | Example Registry Path |
|
|
81
|
+
|--------------|----------------------|
|
|
82
|
+
| Universal content | `.openpackage/commands/test.md` |
|
|
83
|
+
| Root-level content | `<dir>/helper.md` |
|
|
84
|
+
| Root files | `AGENTS.md` |
|
|
85
|
+
|
|
86
|
+
**Rules:**
|
|
87
|
+
|
|
88
|
+
- Universal subdir content **always** has `.openpackage/` prefix
|
|
89
|
+
- Root-level content uses its natural path (no prefix)
|
|
90
|
+
- Root files use their filename directly
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
#### Install Mapping Examples
|
|
95
|
+
|
|
96
|
+
**Universal content** (platform-specific mapping):
|
|
97
|
+
|
|
98
|
+
| Registry Path | Installed Paths |
|
|
99
|
+
|---------------|-----------------|
|
|
100
|
+
| `.openpackage/commands/test.md` | `.cursor/commands/test.md`, `.opencode/commands/test.md`, etc. |
|
|
101
|
+
| `.openpackage/rules/auth.md` | `.cursor/rules/auth.mdc`, etc. |
|
|
102
|
+
|
|
103
|
+
**Root-level content** (1:1 mapping):
|
|
104
|
+
|
|
105
|
+
| Registry Path | Installed Path |
|
|
106
|
+
|---------------|----------------|
|
|
107
|
+
| `<dir>/helper.md` | `<dir>/helper.md` |
|
|
108
|
+
| `AGENTS.md` | `AGENTS.md` |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
#### Consistent Layout Across Locations
|
|
113
|
+
|
|
114
|
+
These layouts apply identically whether the package lives at:
|
|
115
|
+
|
|
116
|
+
- **Workspace root**: `cwd/` (content at `cwd/.openpackage/...`)
|
|
117
|
+
- **Nested package**: `cwd/.openpackage/packages/<name>/` (content at `cwd/.openpackage/packages/<name>/.openpackage/...`)
|
|
118
|
+
- **Registry**: `~/.openpackage/registry/<name>/<version>/` (content at `.../.openpackage/...`)
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
#### Frontmatter and Overrides
|
|
123
|
+
|
|
124
|
+
In the canonical structure:
|
|
125
|
+
|
|
126
|
+
- Each universal markdown file (`.openpackage/<subdir>/<name>.md`) is the **single source of truth** for:
|
|
127
|
+
- Markdown body
|
|
128
|
+
- Shared frontmatter keys/common metadata
|
|
129
|
+
|
|
130
|
+
- Platform overrides live alongside their universal file:
|
|
131
|
+
|
|
132
|
+
```text
|
|
133
|
+
.openpackage/agents/foo.md # universal body + shared frontmatter
|
|
134
|
+
.openpackage/agents/foo.claude.yml # CLAUDE-specific frontmatter diff
|
|
135
|
+
.openpackage/agents/foo.claude.md # optional CLAUDE-specific markdown body
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The save pipeline:
|
|
139
|
+
|
|
140
|
+
1. Normalizes workspace markdown and computes:
|
|
141
|
+
- Universal frontmatter to keep in `foo.md`
|
|
142
|
+
- Per-platform differences to write as `foo.<platform>.yml`
|
|
143
|
+
2. Writes override files into the `.openpackage/<subdir>/` tree
|
|
144
|
+
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
## Platforms system behavior
|
|
2
|
+
|
|
3
|
+
### Overview
|
|
4
|
+
|
|
5
|
+
The platforms system provides a unified way to describe and work with different AI coding platforms (e.g. Cursor, Claude, Gemini) so that OpenPackage can manage platform‑specific rules, commands, agents, and skills consistently.
|
|
6
|
+
|
|
7
|
+
From a user’s perspective, the platform layer answers:
|
|
8
|
+
- **Which platforms are supported in this workspace?**
|
|
9
|
+
- **Where do their files live on disk?**
|
|
10
|
+
- **Which files belong to which platform (or to the generic `ai` space)?**
|
|
11
|
+
- **Which root files (e.g. `CLAUDE.md`) are active, and how are they used?**
|
|
12
|
+
|
|
13
|
+
All platform definitions (names, directories, root files, and subdirectories) are centralized in `platforms.jsonc`.
|
|
14
|
+
|
|
15
|
+
Each platform entry in `platforms.jsonc` has the shape:
|
|
16
|
+
|
|
17
|
+
- `name` (string): Human‑readable display name.
|
|
18
|
+
- `rootDir` (string): Platform root directory (e.g. `.cursor`, `.claude`).
|
|
19
|
+
- `rootFile?` (string): Optional root file at the project root (e.g. `CLAUDE.md`, `QWEN.md`).
|
|
20
|
+
- `subdirs` (object): Map from universal subdir keys (`rules`, `commands`, `agents`, `skills`) to:
|
|
21
|
+
- `path` (string): Directory path under `rootDir`.
|
|
22
|
+
- `exts?` (string[]): Allowed workspace file extensions. When omitted, all extensions are allowed; when an empty array, no extensions are allowed.
|
|
23
|
+
- `transformations?` (array): Optional extension conversion rules with `{ packageExt, workspaceExt }` entries that describe how files convert between registry and workspace formats.
|
|
24
|
+
- `aliases?` (string[]): Optional CLI aliases that resolve to this platform.
|
|
25
|
+
- `enabled?` (boolean): When `false`, the platform exists in config but is treated as disabled.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
### Platform identities and aliases
|
|
30
|
+
|
|
31
|
+
- **Platform id**: each platform has a lowercase id (e.g. `cursor`, `claude`, `gemini`) used throughout the CLI. These ids are the top‑level keys in `platforms.jsonc`.
|
|
32
|
+
- **Enabled flag**:
|
|
33
|
+
- Platforms are considered **enabled by default**.
|
|
34
|
+
- A platform can be explicitly disabled in `platforms.jsonc` via `enabled: false` (e.g. for experimental or unsupported platforms).
|
|
35
|
+
- Functions that list or iterate platforms only include **enabled** platforms by default, with optional flags to include disabled ones when needed.
|
|
36
|
+
- **Aliases**:
|
|
37
|
+
- Each platform can declare **human‑friendly aliases** in its `aliases` array (e.g. `claudecode`, `codexcli`, `geminicli`, `kilocode`, `qwencode`).
|
|
38
|
+
- Aliases are resolved case‑insensitively to a canonical platform id.
|
|
39
|
+
- User‑facing prompts or configs can accept either the platform id or any of its aliases.
|
|
40
|
+
|
|
41
|
+
**Resolution behavior**
|
|
42
|
+
|
|
43
|
+
- Given a string input (e.g. from CLI flags, prompts, or config), the system:
|
|
44
|
+
- First treats it as a platform id (after lowercasing).
|
|
45
|
+
- If there is no direct match, it looks it up in the alias map.
|
|
46
|
+
- If neither match, the platform is treated as **unknown**.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
### Directory layout and universal subdirs
|
|
51
|
+
|
|
52
|
+
Each platform defines:
|
|
53
|
+
- A **root directory** (e.g. `.cursor`, `.claude`, `.gemini`).
|
|
54
|
+
- Optional **root file** at the project root (e.g. `CLAUDE.md`, `GEMINI.md`, `QWEN.md`, `WARP.md`, or the shared `AGENTS.md`).
|
|
55
|
+
- A set of **universal subdirectories**, which describe where different kinds of content live:
|
|
56
|
+
- `rules` – steering/rules files for a platform.
|
|
57
|
+
- `commands` – command/workflow prompt files.
|
|
58
|
+
- `agents` – agent definitions.
|
|
59
|
+
- `skills` – skill or tool definitions.
|
|
60
|
+
|
|
61
|
+
For each subdirectory, the platform definition specifies:
|
|
62
|
+
- **Path** under the platform root (e.g. `.cursor/rules`, `.factory/droids`, `.kilo/workflows`).
|
|
63
|
+
- **Allowed extensions**: which workspace file extensions are considered part of that subdir (e.g. `.md`, `.mdc`, `.toml`). Omit to allow any extension or set an empty list to disallow all files.
|
|
64
|
+
- **Extension transformations**: optional `{ packageExt, workspaceExt }` pairs that describe how files convert between registry/universal formats and platform-specific workspace formats (e.g. Cursor rules convert `.md` registry files to `.mdc` in the workspace).
|
|
65
|
+
|
|
66
|
+
**Examples**
|
|
67
|
+
|
|
68
|
+
- Cursor:
|
|
69
|
+
- Root dir: `.cursor`
|
|
70
|
+
- Subdirs:
|
|
71
|
+
- `rules` → `.cursor/rules` (reads `.mdc` + `.md`, writes `.mdc`)
|
|
72
|
+
- `commands` → `.cursor/commands` (reads/writes `.md`)
|
|
73
|
+
- Claude:
|
|
74
|
+
- Root dir: `.claude`
|
|
75
|
+
- Root file: `CLAUDE.md`
|
|
76
|
+
- Subdirs:
|
|
77
|
+
- `commands` → `.claude/commands`
|
|
78
|
+
- `agents` → `.claude/agents`
|
|
79
|
+
- `skills` → `.claude/skills`
|
|
80
|
+
|
|
81
|
+
The system exposes a **platform directory map** that, given a working directory, tells callers where each platform’s `rules`, `commands`, `agents`, and `skills` live on disk.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### Platform detection
|
|
86
|
+
|
|
87
|
+
The platforms system can **detect which platforms are present** in a workspace using two signals:
|
|
88
|
+
|
|
89
|
+
1. **Platform directories**:
|
|
90
|
+
- For each enabled platform, the system checks whether its root directory exists in the current working directory.
|
|
91
|
+
- If the root directory exists, the platform is marked as **present**.
|
|
92
|
+
|
|
93
|
+
2. **Root files**:
|
|
94
|
+
- For platforms that define a root file (e.g. `CLAUDE.md`, `GEMINI.md`, `QWEN.md`, `WARP.md`), the system checks whether those files exist at the project root.
|
|
95
|
+
- If a root file exists, the corresponding platform is also marked as **present**, even if its standard directory structure is missing.
|
|
96
|
+
- The shared `AGENTS.md` file is treated as **universal** and not attributed to a single platform.
|
|
97
|
+
|
|
98
|
+
The result is:
|
|
99
|
+
- A list of **detection results** (for each platform: `{ name, detected }`).
|
|
100
|
+
- A convenience list of **detected platforms only** (used by higher‑level features like setup flows).
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
### Platform‑specific directories and creation
|
|
105
|
+
|
|
106
|
+
The platforms system provides helpers for:
|
|
107
|
+
|
|
108
|
+
- **Getting directory paths** for each platform:
|
|
109
|
+
- For each enabled platform, callers can retrieve:
|
|
110
|
+
- The `rules` directory path.
|
|
111
|
+
- Optional `commands`, `agents`, and `skills` directory paths.
|
|
112
|
+
- Optional `rootFile` path, if the platform defines one.
|
|
113
|
+
- **Creating missing platform directories**:
|
|
114
|
+
- Given a list of platform ids and a working directory:
|
|
115
|
+
- Ensures the `rules` directory exists for each platform.
|
|
116
|
+
- Creates directories as needed and returns a list of newly created paths.
|
|
117
|
+
|
|
118
|
+
These helpers allow commands like `opkg init` or platform setup flows to create the necessary folder structure for one or more platforms.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
### Validating platform structure
|
|
123
|
+
|
|
124
|
+
For a given platform and working directory, the system can validate:
|
|
125
|
+
- That the `rules` directory exists.
|
|
126
|
+
- That the configured root file (if any) exists.
|
|
127
|
+
|
|
128
|
+
It returns:
|
|
129
|
+
- A simple `{ valid: boolean, issues: string[] }` result:
|
|
130
|
+
- `valid = true` when the platform’s required directories/files are present.
|
|
131
|
+
- `issues` describing any missing or inconsistent paths.
|
|
132
|
+
|
|
133
|
+
This is used by higher‑level commands to surface actionable warnings when a platform’s layout is incomplete.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### File extension behavior
|
|
138
|
+
|
|
139
|
+
For each platform’s `rules` subdir, the system exposes:
|
|
140
|
+
- The **set of file extensions** that are considered valid rules files for that platform.
|
|
141
|
+
- Example: Cursor rules accept `.mdc` and `.md`, Gemini commands accept `.toml`, etc.
|
|
142
|
+
- Higher‑level discovery utilities rely on this to:
|
|
143
|
+
- Filter files by extension when searching for platform content.
|
|
144
|
+
- Decide which files are safe to manage or delete during uninstall/cleanup operations.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
### Universal subdirectory listing
|
|
149
|
+
|
|
150
|
+
For any detected platform, the platforms system can return a **normalized list of its subdirectories**:
|
|
151
|
+
- Each entry includes:
|
|
152
|
+
- The full directory path.
|
|
153
|
+
- The universal label (`rules`, `commands`, `agents`, `skills`).
|
|
154
|
+
- A short leaf name (last path component) for display.
|
|
155
|
+
|
|
156
|
+
This list is consumed by:
|
|
157
|
+
- Discovery utilities that search for platform‑specific files.
|
|
158
|
+
- Uninstall/cleanup flows that remove platform files for a given package.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
### Platform inference from file paths
|
|
163
|
+
|
|
164
|
+
The platforms system helps determine which platform a given file belongs to by:
|
|
165
|
+
|
|
166
|
+
1. **Using path‑to‑platform mappings**:
|
|
167
|
+
- A dedicated mapper converts full workspace paths into a *universal* representation that includes the platform id where possible (e.g. `.cursor/rules/foo.mdc` → platform `cursor` + `rules/foo.mdc`).
|
|
168
|
+
|
|
169
|
+
2. **Checking for generic workspace directories**:
|
|
170
|
+
- Files that do not live under a known platform root (for example, a conventional `ai/` folder) are treated as workspace-level content rather than being assigned to a specific platform.
|
|
171
|
+
|
|
172
|
+
3. **Looking at source directory names**:
|
|
173
|
+
- If a file lives under a known platform root directory (e.g. `.cursor`, `.claude`), the system infers that platform from the directory.
|
|
174
|
+
|
|
175
|
+
4. **Parsing registry paths with platform suffixes**:
|
|
176
|
+
- As a final fallback, the system inspects registry paths for explicit platform suffixes (e.g. `rules/file.cursor.md`) and maps them back to a platform id when possible.
|
|
177
|
+
|
|
178
|
+
The result is a best‑effort platform id (or a `workspace` classification) for a given file, which other components use to route content to the right registry paths and conflict‑resolution logic.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
### Root file handling
|
|
183
|
+
|
|
184
|
+
The platforms system exposes **all known platform root filenames**, derived from the `rootFile` fields in `platforms.jsonc` plus the universal `AGENTS.md`. These are used to:
|
|
185
|
+
- Discover root files in the workspace or in the local registry.
|
|
186
|
+
- Map root files back to platforms (except for universal `AGENTS.md`).
|
|
187
|
+
- Coordinate how content from multiple platform‑specific root files is merged or extracted into a universal view (handled by other utilities).
|
|
188
|
+
|
|
189
|
+
From a behavioral perspective:
|
|
190
|
+
- Platforms that define root files can participate in root‑file‑based flows (e.g. reading/writing `CLAUDE.md`).
|
|
191
|
+
- Platforms without root files rely exclusively on their directory layout (`.cursor/rules`, `.kilo/workflows`, etc.).
|
|
192
|
+
|
|
193
|
+
|