opkg 0.9.2 → 0.9.4
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/.claude/agents/code-reviewer.md +171 -0
- package/.claude/commands/commit-push-pr.md +20 -0
- package/.claude/commands/{specs/read.md → read-specs.md} +1 -1
- package/.claude/commands/{specs/update.md → update-specs.md} +4 -0
- package/.claude/skills/code-review-excellence/SKILL.md +538 -0
- package/README.md +2 -2
- package/package.json +3 -1
- package/packages/cli/dist/add-IJAPFHIX.js +624 -0
- package/packages/cli/dist/add-IJAPFHIX.js.map +7 -0
- package/packages/cli/dist/add-LLUNFLJI.js +624 -0
- package/packages/cli/dist/add-LLUNFLJI.js.map +7 -0
- package/packages/cli/dist/add-U44SL3OR.js +624 -0
- package/packages/cli/dist/add-U44SL3OR.js.map +7 -0
- package/packages/cli/dist/chunk-23VBP5L6.js +371 -0
- package/packages/cli/dist/chunk-23VBP5L6.js.map +7 -0
- package/packages/cli/dist/chunk-2SVHLF5C.js +1419 -0
- package/packages/cli/dist/chunk-2SVHLF5C.js.map +7 -0
- package/packages/cli/dist/chunk-37256POU.js +99 -0
- package/packages/cli/dist/chunk-37256POU.js.map +7 -0
- package/packages/cli/dist/chunk-3PZRVA6O.js +196 -0
- package/packages/cli/dist/chunk-3PZRVA6O.js.map +7 -0
- package/packages/cli/dist/chunk-427DCURL.js +155 -0
- package/packages/cli/dist/chunk-427DCURL.js.map +7 -0
- package/packages/cli/dist/chunk-4B5HJLP2.js +48 -0
- package/packages/cli/dist/chunk-4B5HJLP2.js.map +7 -0
- package/packages/cli/dist/chunk-4OWT3YEG.js +413 -0
- package/packages/cli/dist/chunk-4OWT3YEG.js.map +7 -0
- package/packages/cli/dist/chunk-4RIBTBXI.js +568 -0
- package/packages/cli/dist/chunk-4RIBTBXI.js.map +7 -0
- package/packages/cli/dist/chunk-4X2EJHJN.js +63 -0
- package/packages/cli/dist/chunk-4X2EJHJN.js.map +7 -0
- package/packages/cli/dist/chunk-6CYW66HD.js +1136 -0
- package/packages/cli/dist/chunk-6CYW66HD.js.map +7 -0
- package/packages/cli/dist/chunk-6DITYAFA.js +172 -0
- package/packages/cli/dist/chunk-6DITYAFA.js.map +7 -0
- package/packages/cli/dist/chunk-7KEAKEVZ.js +568 -0
- package/packages/cli/dist/chunk-7KEAKEVZ.js.map +7 -0
- package/packages/cli/dist/chunk-ABFUD25D.js +61 -0
- package/packages/cli/dist/chunk-ABFUD25D.js.map +7 -0
- package/packages/cli/dist/chunk-AR7GJCG6.js +274 -0
- package/packages/cli/dist/chunk-AR7GJCG6.js.map +7 -0
- package/packages/cli/dist/chunk-AYTGQCXH.js +86 -0
- package/packages/cli/dist/chunk-AYTGQCXH.js.map +7 -0
- package/packages/cli/dist/chunk-BROJ6OUT.js +631 -0
- package/packages/cli/dist/chunk-BROJ6OUT.js.map +7 -0
- package/packages/cli/dist/chunk-BVVSU7QD.js +23 -0
- package/packages/cli/dist/chunk-BVVSU7QD.js.map +7 -0
- package/packages/cli/dist/chunk-C6FY55UP.js +108 -0
- package/packages/cli/dist/chunk-C6FY55UP.js.map +7 -0
- package/packages/cli/dist/chunk-CVA64SXK.js +1136 -0
- package/packages/cli/dist/chunk-CVA64SXK.js.map +7 -0
- package/packages/cli/dist/chunk-D3O7LY2Q.js +1151 -0
- package/packages/cli/dist/chunk-D3O7LY2Q.js.map +7 -0
- package/packages/cli/dist/chunk-D6LEPODL.js +413 -0
- package/packages/cli/dist/chunk-D6LEPODL.js.map +7 -0
- package/packages/cli/dist/chunk-DEC24S7E.js +186 -0
- package/packages/cli/dist/chunk-DEC24S7E.js.map +7 -0
- package/packages/cli/dist/chunk-FMVVJH5M.js +371 -0
- package/packages/cli/dist/chunk-FMVVJH5M.js.map +7 -0
- package/packages/cli/dist/chunk-GDVFS3YP.js +130 -0
- package/packages/cli/dist/chunk-GDVFS3YP.js.map +7 -0
- package/packages/cli/dist/chunk-GEP2G5HF.js +31 -0
- package/packages/cli/dist/chunk-GEP2G5HF.js.map +7 -0
- package/packages/cli/dist/chunk-GSWHZBT2.js +62 -0
- package/packages/cli/dist/chunk-GSWHZBT2.js.map +7 -0
- package/packages/cli/dist/chunk-HTYHJA3B.js +61 -0
- package/packages/cli/dist/chunk-HTYHJA3B.js.map +7 -0
- package/packages/cli/dist/chunk-HYKYECAE.js +222 -0
- package/packages/cli/dist/chunk-HYKYECAE.js.map +7 -0
- package/packages/cli/dist/chunk-I7FEAHB4.js +100 -0
- package/packages/cli/dist/chunk-I7FEAHB4.js.map +7 -0
- package/packages/cli/dist/chunk-IHVZ5AUJ.js +107 -0
- package/packages/cli/dist/chunk-IHVZ5AUJ.js.map +7 -0
- package/packages/cli/dist/chunk-KI7FDU3H.js +99 -0
- package/packages/cli/dist/chunk-KI7FDU3H.js.map +7 -0
- package/packages/cli/dist/chunk-L5GRJQBS.js +32 -0
- package/packages/cli/dist/chunk-L5GRJQBS.js.map +7 -0
- package/packages/cli/dist/chunk-LHEAUDJL.js +302 -0
- package/packages/cli/dist/chunk-LHEAUDJL.js.map +7 -0
- package/packages/cli/dist/chunk-MIURCESJ.js +48 -0
- package/packages/cli/dist/chunk-MIURCESJ.js.map +7 -0
- package/packages/cli/dist/chunk-N43IXOND.js +732 -0
- package/packages/cli/dist/chunk-N43IXOND.js.map +7 -0
- package/packages/cli/dist/chunk-OUZRMGPV.js +274 -0
- package/packages/cli/dist/chunk-OUZRMGPV.js.map +7 -0
- package/packages/cli/dist/chunk-PSQXKAL4.js +371 -0
- package/packages/cli/dist/chunk-PSQXKAL4.js.map +7 -0
- package/packages/cli/dist/chunk-PUDRKDVZ.js +1419 -0
- package/packages/cli/dist/chunk-PUDRKDVZ.js.map +7 -0
- package/packages/cli/dist/chunk-RAKMX654.js +631 -0
- package/packages/cli/dist/chunk-RAKMX654.js.map +7 -0
- package/packages/cli/dist/chunk-RSFLK2TP.js +195 -0
- package/packages/cli/dist/chunk-RSFLK2TP.js.map +7 -0
- package/packages/cli/dist/chunk-S26PR2BS.js +99 -0
- package/packages/cli/dist/chunk-S26PR2BS.js.map +7 -0
- package/packages/cli/dist/chunk-U7FW7SXX.js +568 -0
- package/packages/cli/dist/chunk-U7FW7SXX.js.map +7 -0
- package/packages/cli/dist/chunk-VKM6K5TN.js +413 -0
- package/packages/cli/dist/chunk-VKM6K5TN.js.map +7 -0
- package/packages/cli/dist/chunk-VKNJG4JN.js +253 -0
- package/packages/cli/dist/chunk-VKNJG4JN.js.map +7 -0
- package/packages/cli/dist/chunk-VQ2KY6CK.js +113 -0
- package/packages/cli/dist/chunk-VQ2KY6CK.js.map +7 -0
- package/packages/cli/dist/chunk-VQDTXLOX.js +1312 -0
- package/packages/cli/dist/chunk-VQDTXLOX.js.map +7 -0
- package/packages/cli/dist/chunk-VXNS3X5O.js +60 -0
- package/packages/cli/dist/chunk-VXNS3X5O.js.map +7 -0
- package/packages/cli/dist/chunk-WF7H2YDU.js +376 -0
- package/packages/cli/dist/chunk-WF7H2YDU.js.map +7 -0
- package/packages/cli/dist/chunk-WNRXZLWW.js +266 -0
- package/packages/cli/dist/chunk-WNRXZLWW.js.map +7 -0
- package/packages/cli/dist/chunk-WT4VVCXM.js +1121 -0
- package/packages/cli/dist/chunk-WT4VVCXM.js.map +7 -0
- package/packages/cli/dist/configure-3AZUMDJZ.js +107 -0
- package/packages/cli/dist/configure-3AZUMDJZ.js.map +7 -0
- package/packages/cli/dist/configure-D722JQOD.js +107 -0
- package/packages/cli/dist/configure-D722JQOD.js.map +7 -0
- package/packages/cli/dist/configure-IU5H7XD6.js +107 -0
- package/packages/cli/dist/configure-IU5H7XD6.js.map +7 -0
- package/packages/cli/dist/file-format-detector-PXCIAKTK.js +22 -0
- package/packages/cli/dist/file-format-detector-PXCIAKTK.js.map +7 -0
- package/packages/cli/dist/index.js +17 -17
- package/packages/cli/dist/install-EZNWMLJR.js +7581 -0
- package/packages/cli/dist/install-EZNWMLJR.js.map +7 -0
- package/packages/cli/dist/install-F5ANFUBX.js +7577 -0
- package/packages/cli/dist/install-F5ANFUBX.js.map +7 -0
- package/packages/cli/dist/install-JSXEPPC2.js +7104 -0
- package/packages/cli/dist/install-JSXEPPC2.js.map +7 -0
- package/packages/cli/dist/install-QHEBX7JH.js +7101 -0
- package/packages/cli/dist/install-QHEBX7JH.js.map +7 -0
- package/packages/cli/dist/list-DMOUATYI.js +327 -0
- package/packages/cli/dist/list-DMOUATYI.js.map +7 -0
- package/packages/cli/dist/list-UESSCB7Y.js +327 -0
- package/packages/cli/dist/list-UESSCB7Y.js.map +7 -0
- package/packages/cli/dist/list-XR7RSJFS.js +327 -0
- package/packages/cli/dist/list-XR7RSJFS.js.map +7 -0
- package/packages/cli/dist/login-EYZ2SOYZ.js +150 -0
- package/packages/cli/dist/login-EYZ2SOYZ.js.map +7 -0
- package/packages/cli/dist/login-JWCSTAEU.js +150 -0
- package/packages/cli/dist/login-JWCSTAEU.js.map +7 -0
- package/packages/cli/dist/login-NRKHXZKM.js +150 -0
- package/packages/cli/dist/login-NRKHXZKM.js.map +7 -0
- package/packages/cli/dist/logout-HDMYRXIE.js +40 -0
- package/packages/cli/dist/logout-HDMYRXIE.js.map +7 -0
- package/packages/cli/dist/logout-SYHXCVCQ.js +40 -0
- package/packages/cli/dist/logout-SYHXCVCQ.js.map +7 -0
- package/packages/cli/dist/logout-X3XUUOH5.js +40 -0
- package/packages/cli/dist/logout-X3XUUOH5.js.map +7 -0
- package/packages/cli/dist/new-3LTFKDTQ.js +277 -0
- package/packages/cli/dist/new-3LTFKDTQ.js.map +7 -0
- package/packages/cli/dist/new-F46OSD72.js +277 -0
- package/packages/cli/dist/new-F46OSD72.js.map +7 -0
- package/packages/cli/dist/new-OPCCLNL2.js +277 -0
- package/packages/cli/dist/new-OPCCLNL2.js.map +7 -0
- package/packages/cli/dist/package-marker-detector-T5O5YD2E.js +80 -0
- package/packages/cli/dist/package-marker-detector-T5O5YD2E.js.map +7 -0
- package/packages/cli/dist/package-yml-QWZIJDYU.js +16 -0
- package/packages/cli/dist/package-yml-QWZIJDYU.js.map +7 -0
- package/packages/cli/dist/plugin-naming-YP2I4NPA.js +29 -0
- package/packages/cli/dist/plugin-naming-YP2I4NPA.js.map +7 -0
- package/packages/cli/dist/publish-4H43PCSG.js +619 -0
- package/packages/cli/dist/publish-4H43PCSG.js.map +7 -0
- package/packages/cli/dist/publish-RULKLNUX.js +619 -0
- package/packages/cli/dist/publish-RULKLNUX.js.map +7 -0
- package/packages/cli/dist/publish-URWY2P3E.js +619 -0
- package/packages/cli/dist/publish-URWY2P3E.js.map +7 -0
- package/packages/cli/dist/remove-BD52BHR2.js +542 -0
- package/packages/cli/dist/remove-BD52BHR2.js.map +7 -0
- package/packages/cli/dist/remove-G5NRC7LD.js +542 -0
- package/packages/cli/dist/remove-G5NRC7LD.js.map +7 -0
- package/packages/cli/dist/remove-TC3FQUYQ.js +542 -0
- package/packages/cli/dist/remove-TC3FQUYQ.js.map +7 -0
- package/packages/cli/dist/resource-discoverer-4X4RY43E.js +17 -0
- package/packages/cli/dist/resource-discoverer-4X4RY43E.js.map +7 -0
- package/packages/cli/dist/save-24TESYKI.js +1728 -0
- package/packages/cli/dist/save-24TESYKI.js.map +7 -0
- package/packages/cli/dist/save-N3QWF2WN.js +1728 -0
- package/packages/cli/dist/save-N3QWF2WN.js.map +7 -0
- package/packages/cli/dist/save-P2U67DTV.js +1728 -0
- package/packages/cli/dist/save-P2U67DTV.js.map +7 -0
- package/packages/cli/dist/search-ABROK3UO.js +157 -0
- package/packages/cli/dist/search-ABROK3UO.js.map +7 -0
- package/packages/cli/dist/search-WVFXFNAV.js +157 -0
- package/packages/cli/dist/search-WVFXFNAV.js.map +7 -0
- package/packages/cli/dist/search-YQN2Q2SO.js +157 -0
- package/packages/cli/dist/search-YQN2Q2SO.js.map +7 -0
- package/packages/cli/dist/set-DCWF73F6.js +251 -0
- package/packages/cli/dist/set-DCWF73F6.js.map +7 -0
- package/packages/cli/dist/set-GJEG2F6Y.js +251 -0
- package/packages/cli/dist/set-GJEG2F6Y.js.map +7 -0
- package/packages/cli/dist/set-NGM2FIKF.js +251 -0
- package/packages/cli/dist/set-NGM2FIKF.js.map +7 -0
- package/packages/cli/dist/uninstall-3CJQMTYH.js +539 -0
- package/packages/cli/dist/uninstall-3CJQMTYH.js.map +7 -0
- package/packages/cli/dist/uninstall-Q3CP4UN5.js +539 -0
- package/packages/cli/dist/uninstall-Q3CP4UN5.js.map +7 -0
- package/packages/cli/dist/uninstall-QU5OMEEC.js +539 -0
- package/packages/cli/dist/uninstall-QU5OMEEC.js.map +7 -0
- package/packages/cli/dist/unpublish-GHJQYC4S.js +245 -0
- package/packages/cli/dist/unpublish-GHJQYC4S.js.map +7 -0
- package/packages/cli/dist/unpublish-L2CYMK4B.js +245 -0
- package/packages/cli/dist/unpublish-L2CYMK4B.js.map +7 -0
- package/packages/cli/dist/unpublish-VBTNTMS5.js +245 -0
- package/packages/cli/dist/unpublish-VBTNTMS5.js.map +7 -0
- package/packages/cli/dist/view-MXRBMXOG.js +488 -0
- package/packages/cli/dist/view-MXRBMXOG.js.map +7 -0
- package/packages/cli/dist/view-NMND7SAW.js +488 -0
- package/packages/cli/dist/view-NMND7SAW.js.map +7 -0
- package/packages/cli/dist/view-RPQRDSYB.js +488 -0
- package/packages/cli/dist/view-RPQRDSYB.js.map +7 -0
- package/packages/cli/package.json +2 -0
- package/packages/core/dist/constants/index.d.ts +9 -0
- package/packages/core/dist/constants/index.d.ts.map +1 -1
- package/packages/core/dist/constants/index.js +12 -0
- package/packages/core/dist/constants/index.js.map +1 -1
- package/packages/core/dist/core/dependency-resolver/index.d.ts +2 -10
- package/packages/core/dist/core/dependency-resolver/index.d.ts.map +1 -1
- package/packages/core/dist/core/dependency-resolver/index.js +3 -14
- package/packages/core/dist/core/dependency-resolver/index.js.map +1 -1
- package/packages/core/dist/core/install/base-detector.d.ts +2 -1
- package/packages/core/dist/core/install/base-detector.d.ts.map +1 -1
- package/packages/core/dist/core/install/base-detector.js +54 -1
- package/packages/core/dist/core/install/base-detector.js.map +1 -1
- package/packages/core/dist/core/install/conflicts/file-conflict-resolver.d.ts +7 -5
- package/packages/core/dist/core/install/conflicts/file-conflict-resolver.d.ts.map +1 -1
- package/packages/core/dist/core/install/conflicts/file-conflict-resolver.js +25 -9
- package/packages/core/dist/core/install/conflicts/file-conflict-resolver.js.map +1 -1
- package/packages/core/dist/core/install/flow-index-installer.d.ts +2 -1
- package/packages/core/dist/core/install/flow-index-installer.d.ts.map +1 -1
- package/packages/core/dist/core/install/flow-index-installer.js +19 -4
- package/packages/core/dist/core/install/flow-index-installer.js.map +1 -1
- package/packages/core/dist/core/install/input-classifier-base.js +3 -3
- package/packages/core/dist/core/install/input-classifier-base.js.map +1 -1
- package/packages/core/dist/core/install/install-reporting.d.ts.map +1 -1
- package/packages/core/dist/core/install/install-reporting.js +7 -9
- package/packages/core/dist/core/install/install-reporting.js.map +1 -1
- package/packages/core/dist/core/install/list-handler.d.ts.map +1 -1
- package/packages/core/dist/core/install/list-handler.js +3 -0
- package/packages/core/dist/core/install/list-handler.js.map +1 -1
- package/packages/core/dist/core/install/marketplace-handler.d.ts.map +1 -1
- package/packages/core/dist/core/install/marketplace-handler.js.map +1 -1
- package/packages/core/dist/core/install/operations/conflict-handler.d.ts +2 -1
- package/packages/core/dist/core/install/operations/conflict-handler.d.ts.map +1 -1
- package/packages/core/dist/core/install/operations/conflict-handler.js +2 -2
- package/packages/core/dist/core/install/operations/conflict-handler.js.map +1 -1
- package/packages/core/dist/core/install/operations/installation-executor.d.ts +3 -0
- package/packages/core/dist/core/install/operations/installation-executor.d.ts.map +1 -1
- package/packages/core/dist/core/install/operations/installation-executor.js +39 -22
- package/packages/core/dist/core/install/operations/installation-executor.js.map +1 -1
- package/packages/core/dist/core/install/orchestrator/orchestrator.d.ts +7 -3
- package/packages/core/dist/core/install/orchestrator/orchestrator.d.ts.map +1 -1
- package/packages/core/dist/core/install/orchestrator/orchestrator.js +193 -93
- package/packages/core/dist/core/install/orchestrator/orchestrator.js.map +1 -1
- package/packages/core/dist/core/install/orchestrator/strategies/git-strategy.d.ts +1 -0
- package/packages/core/dist/core/install/orchestrator/strategies/git-strategy.d.ts.map +1 -1
- package/packages/core/dist/core/install/orchestrator/strategies/git-strategy.js +11 -24
- package/packages/core/dist/core/install/orchestrator/strategies/git-strategy.js.map +1 -1
- package/packages/core/dist/core/install/orchestrator/strategies/path-strategy.d.ts +2 -0
- package/packages/core/dist/core/install/orchestrator/strategies/path-strategy.d.ts.map +1 -1
- package/packages/core/dist/core/install/orchestrator/strategies/path-strategy.js +14 -14
- package/packages/core/dist/core/install/orchestrator/strategies/path-strategy.js.map +1 -1
- package/packages/core/dist/core/install/orchestrator/strategies/registry-strategy.d.ts +7 -0
- package/packages/core/dist/core/install/orchestrator/strategies/registry-strategy.d.ts.map +1 -1
- package/packages/core/dist/core/install/orchestrator/strategies/registry-strategy.js +28 -0
- package/packages/core/dist/core/install/orchestrator/strategies/registry-strategy.js.map +1 -1
- package/packages/core/dist/core/install/orchestrator/types.d.ts +2 -0
- package/packages/core/dist/core/install/orchestrator/types.d.ts.map +1 -1
- package/packages/core/dist/core/install/path-package-loader.d.ts.map +1 -1
- package/packages/core/dist/core/install/path-package-loader.js +20 -1
- package/packages/core/dist/core/install/path-package-loader.js.map +1 -1
- package/packages/core/dist/core/install/platform-resolution.d.ts +3 -0
- package/packages/core/dist/core/install/platform-resolution.d.ts.map +1 -1
- package/packages/core/dist/core/install/platform-resolution.js +5 -2
- package/packages/core/dist/core/install/platform-resolution.js.map +1 -1
- package/packages/core/dist/core/install/preprocessing/context-population.d.ts +18 -0
- package/packages/core/dist/core/install/preprocessing/context-population.d.ts.map +1 -0
- package/packages/core/dist/core/install/preprocessing/context-population.js +36 -0
- package/packages/core/dist/core/install/preprocessing/context-population.js.map +1 -0
- package/packages/core/dist/core/install/preprocessing/convenience-preprocessor.d.ts +23 -0
- package/packages/core/dist/core/install/preprocessing/convenience-preprocessor.d.ts.map +1 -1
- package/packages/core/dist/core/install/preprocessing/convenience-preprocessor.js +44 -0
- package/packages/core/dist/core/install/preprocessing/convenience-preprocessor.js.map +1 -1
- package/packages/core/dist/core/install/sources/git-source.d.ts.map +1 -1
- package/packages/core/dist/core/install/sources/git-source.js +67 -4
- package/packages/core/dist/core/install/sources/git-source.js.map +1 -1
- package/packages/core/dist/core/install/sources/path-source.d.ts.map +1 -1
- package/packages/core/dist/core/install/sources/path-source.js +8 -0
- package/packages/core/dist/core/install/sources/path-source.js.map +1 -1
- package/packages/core/dist/core/install/strategies/flow-based-strategy.d.ts.map +1 -1
- package/packages/core/dist/core/install/strategies/flow-based-strategy.js +12 -5
- package/packages/core/dist/core/install/strategies/flow-based-strategy.js.map +1 -1
- package/packages/core/dist/core/install/strategies/types.d.ts +11 -1
- package/packages/core/dist/core/install/strategies/types.d.ts.map +1 -1
- package/packages/core/dist/core/install/unified/context-builders.d.ts +5 -0
- package/packages/core/dist/core/install/unified/context-builders.d.ts.map +1 -1
- package/packages/core/dist/core/install/unified/context-builders.js +12 -0
- package/packages/core/dist/core/install/unified/context-builders.js.map +1 -1
- package/packages/core/dist/core/install/unified/context-helpers.d.ts +0 -4
- package/packages/core/dist/core/install/unified/context-helpers.d.ts.map +1 -1
- package/packages/core/dist/core/install/unified/context-helpers.js +0 -24
- package/packages/core/dist/core/install/unified/context-helpers.js.map +1 -1
- package/packages/core/dist/core/install/unified/index.d.ts +1 -1
- package/packages/core/dist/core/install/unified/index.d.ts.map +1 -1
- package/packages/core/dist/core/install/unified/index.js +1 -1
- package/packages/core/dist/core/install/unified/index.js.map +1 -1
- package/packages/core/dist/core/install/unified/multi-context-pipeline.d.ts +6 -0
- package/packages/core/dist/core/install/unified/multi-context-pipeline.d.ts.map +1 -1
- package/packages/core/dist/core/install/unified/multi-context-pipeline.js +11 -4
- package/packages/core/dist/core/install/unified/multi-context-pipeline.js.map +1 -1
- package/packages/core/dist/core/install/unified/phases/conflicts.d.ts.map +1 -1
- package/packages/core/dist/core/install/unified/phases/conflicts.js +1 -1
- package/packages/core/dist/core/install/unified/phases/conflicts.js.map +1 -1
- package/packages/core/dist/core/install/unified/phases/execute.d.ts.map +1 -1
- package/packages/core/dist/core/install/unified/phases/execute.js +5 -5
- package/packages/core/dist/core/install/unified/phases/execute.js.map +1 -1
- package/packages/core/dist/core/install/unified/phases/load-package.js +3 -3
- package/packages/core/dist/core/install/unified/phases/load-package.js.map +1 -1
- package/packages/core/dist/core/install/unified/phases/report.js +1 -1
- package/packages/core/dist/core/install/unified/phases/report.js.map +1 -1
- package/packages/core/dist/core/install/unified/pipeline.d.ts.map +1 -1
- package/packages/core/dist/core/install/unified/pipeline.js +7 -10
- package/packages/core/dist/core/install/unified/pipeline.js.map +1 -1
- package/packages/core/dist/core/install/wave-resolver/content-root-cache.d.ts +24 -0
- package/packages/core/dist/core/install/wave-resolver/content-root-cache.d.ts.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/content-root-cache.js +71 -0
- package/packages/core/dist/core/install/wave-resolver/content-root-cache.js.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/context-builder.d.ts +39 -0
- package/packages/core/dist/core/install/wave-resolver/context-builder.d.ts.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/context-builder.js +148 -0
- package/packages/core/dist/core/install/wave-resolver/context-builder.js.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/fetcher.d.ts +49 -0
- package/packages/core/dist/core/install/wave-resolver/fetcher.d.ts.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/fetcher.js +221 -0
- package/packages/core/dist/core/install/wave-resolver/fetcher.js.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/index-updater.d.ts +23 -0
- package/packages/core/dist/core/install/wave-resolver/index-updater.d.ts.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/index-updater.js +87 -0
- package/packages/core/dist/core/install/wave-resolver/index-updater.js.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/index-write-collector.d.ts +101 -0
- package/packages/core/dist/core/install/wave-resolver/index-write-collector.d.ts.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/index-write-collector.js +194 -0
- package/packages/core/dist/core/install/wave-resolver/index-write-collector.js.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/index.d.ts +17 -0
- package/packages/core/dist/core/install/wave-resolver/index.d.ts.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/index.js +16 -0
- package/packages/core/dist/core/install/wave-resolver/index.js.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/manifest-reader.d.ts +34 -0
- package/packages/core/dist/core/install/wave-resolver/manifest-reader.d.ts.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/manifest-reader.js +112 -0
- package/packages/core/dist/core/install/wave-resolver/manifest-reader.js.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/types.d.ts +210 -0
- package/packages/core/dist/core/install/wave-resolver/types.d.ts.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/types.js +6 -0
- package/packages/core/dist/core/install/wave-resolver/types.js.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/version-solver.d.ts +65 -0
- package/packages/core/dist/core/install/wave-resolver/version-solver.d.ts.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/version-solver.js +166 -0
- package/packages/core/dist/core/install/wave-resolver/version-solver.js.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/wave-engine.d.ts +16 -0
- package/packages/core/dist/core/install/wave-resolver/wave-engine.d.ts.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/wave-engine.js +337 -0
- package/packages/core/dist/core/install/wave-resolver/wave-engine.js.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/wave-installer.d.ts +50 -0
- package/packages/core/dist/core/install/wave-resolver/wave-installer.d.ts.map +1 -0
- package/packages/core/dist/core/install/wave-resolver/wave-installer.js +246 -0
- package/packages/core/dist/core/install/wave-resolver/wave-installer.js.map +1 -0
- package/packages/core/dist/core/ports/buffered-output.d.ts +36 -0
- package/packages/core/dist/core/ports/buffered-output.d.ts.map +1 -0
- package/packages/core/dist/core/ports/buffered-output.js +89 -0
- package/packages/core/dist/core/ports/buffered-output.js.map +1 -0
- package/packages/core/dist/core/ports/resolve.d.ts +0 -13
- package/packages/core/dist/core/ports/resolve.d.ts.map +1 -1
- package/packages/core/dist/core/ports/resolve.js +0 -28
- package/packages/core/dist/core/ports/resolve.js.map +1 -1
- package/packages/core/dist/core/remove/removal-confirmation.d.ts +4 -1
- package/packages/core/dist/core/remove/removal-confirmation.d.ts.map +1 -1
- package/packages/core/dist/core/remove/removal-confirmation.js +5 -4
- package/packages/core/dist/core/remove/removal-confirmation.js.map +1 -1
- package/packages/core/dist/core/remove/remove-from-source-pipeline.d.ts.map +1 -1
- package/packages/core/dist/core/remove/remove-from-source-pipeline.js +1 -10
- package/packages/core/dist/core/remove/remove-from-source-pipeline.js.map +1 -1
- package/packages/core/dist/core/uninstall/uninstall-executor.js +1 -1
- package/packages/core/dist/core/uninstall/uninstall-executor.js.map +1 -1
- package/packages/core/dist/core/uninstall/uninstall-reporter.d.ts +2 -2
- package/packages/core/dist/core/uninstall/uninstall-reporter.d.ts.map +1 -1
- package/packages/core/dist/core/uninstall/uninstall-reporter.js +4 -4
- package/packages/core/dist/core/uninstall/uninstall-reporter.js.map +1 -1
- package/packages/core/dist/index.d.ts +1 -1
- package/packages/core/dist/index.d.ts.map +1 -1
- package/packages/core/dist/types/execution-context.d.ts +40 -10
- package/packages/core/dist/types/execution-context.d.ts.map +1 -1
- package/packages/core/dist/utils/concurrency-pool.d.ts +34 -0
- package/packages/core/dist/utils/concurrency-pool.d.ts.map +1 -0
- package/packages/core/dist/utils/concurrency-pool.js +58 -0
- package/packages/core/dist/utils/concurrency-pool.js.map +1 -0
- package/packages/core/dist/utils/plugin-naming.d.ts +11 -3
- package/packages/core/dist/utils/plugin-naming.d.ts.map +1 -1
- package/packages/core/dist/utils/plugin-naming.js +27 -7
- package/packages/core/dist/utils/plugin-naming.js.map +1 -1
- package/plans/wave-resolver.md +254 -0
- package/.claude/agents/essentials/code-simplifier.md +0 -52
- package/.claude/commands/essentials/cleanup.md +0 -1
- package/.claude/commands/essentials/review.md +0 -8
- package/.claude/commands/git/commit.md +0 -5
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../core/src/core/scoping/package-scoping.ts"],
|
|
4
|
+
"sourcesContent": ["import { SCOPED_PACKAGE_REGEX, GITHUB_PACKAGE_REGEX, normalizePackageName, validatePackageName, isScopedName } from '../../utils/package-name.js';\n\nexport { isScopedName } from '../../utils/package-name.js';\nimport { listAllPackages, getPackagePath } from '../directory.js';\nimport { exists } from '../../utils/fs.js';\nimport { configManager } from '../config.js';\nimport type { PromptPort } from '../ports/prompt.js';\nimport { resolvePrompt } from '../ports/resolve.js';\nimport { UserCancellationError } from '../../utils/errors.js';\n\n/**\n * Extract the local (non-scope) part from a package name.\n */\nexport function getLocalPart(name: string): string {\n const match = name.match(SCOPED_PACKAGE_REGEX);\n return match ? match[2] : name;\n}\n\n/**\n * Get all scoped package names in the local registry that share the same local name.\n */\nconst PACKAGE_LIST_CACHE_TTL_MS = 5000;\nlet cachedPackageList: string[] | null = null;\nlet cachedPackageListTimestamp = 0;\n\nasync function getCachedPackageList(): Promise<string[]> {\n const now = Date.now();\n if (cachedPackageList && now - cachedPackageListTimestamp < PACKAGE_LIST_CACHE_TTL_MS) {\n return cachedPackageList;\n }\n\n cachedPackageList = await listAllPackages();\n cachedPackageListTimestamp = now;\n return cachedPackageList;\n}\n\nexport async function findScopedVariantsInRegistry(baseName: string): Promise<string[]> {\n const normalizedBase = normalizePackageName(baseName);\n const packages = await getCachedPackageList();\n\n return packages.filter(candidate => {\n const match = candidate.match(SCOPED_PACKAGE_REGEX);\n if (!match) {\n return false;\n }\n const localPart = normalizePackageName(match[2]);\n return localPart === normalizedBase;\n });\n}\n\nasync function isPackageNameTaken(name: string): Promise<boolean> {\n const normalized = normalizePackageName(name);\n return await exists(getPackagePath(normalized));\n}\n\nfunction buildScopedNameFromScope(unscopedName: string, scope: string): string {\n const normalizedScope = normalizePackageName(scope.replace(/^@/, ''));\n const normalizedName = normalizePackageName(unscopedName);\n return `@${normalizedScope}/${normalizedName}`;\n}\n\nasync function ensureScopedNameAvailable(name: string): Promise<void> {\n try {\n validatePackageName(name);\n } catch (error) {\n throw new Error((error as Error).message.replace('%s', name));\n }\n\n if (!isScopedName(name)) {\n throw new Error('Name must be scoped (e.g. @scope/name)');\n }\n\n if (await isPackageNameTaken(name)) {\n throw new Error(\n `Package '${name}' already exists in local registry. Choose a different scoped name.`\n );\n }\n}\n\n/**\n * Fetch the configured default scope for a given profile (if any).\n */\nexport async function getDefaultScopeForProfile(profileName?: string): Promise<string | undefined> {\n if (!profileName) {\n return undefined;\n }\n\n const config = await configManager.getAll();\n const profileConfig = config.profiles?.[profileName];\n return profileConfig?.defaults?.scope;\n}\n\n/**\n * Suggest a scoped package name using the configured default scope.\n */\nexport async function suggestScopedNameFromConfig(\n unscopedName: string,\n profileName?: string\n): Promise<string | undefined> {\n const defaultScope = await getDefaultScopeForProfile(profileName);\n if (!defaultScope) {\n return undefined;\n }\n\n const normalizedScope = normalizePackageName(defaultScope.replace(/^@/, ''));\n const normalizedName = normalizePackageName(unscopedName);\n return `@${normalizedScope}/${normalizedName}`;\n}\n\n/**\n * Prompt user for a new scoped name and ensure it does not already exist locally.\n */\nexport async function promptForNewScopedName(\n baseName: string,\n profileName?: string,\n message?: string,\n prompt?: PromptPort\n): Promise<string> {\n const prm = prompt ?? resolvePrompt();\n const initial = await suggestScopedNameFromConfig(baseName, profileName);\n\n const scopedName = await prm.text(\n message ?? `Enter a scoped name for '${baseName}' (format @scope/${baseName}):`,\n {\n initial,\n validate: async (value: string) => {\n if (!value) return 'Name is required';\n try {\n await ensureScopedNameAvailable(value);\n return true;\n } catch (error) {\n return (error as Error).message;\n }\n }\n }\n );\n\n if (!scopedName) {\n throw new UserCancellationError('Operation cancelled by user');\n }\n\n return normalizePackageName(scopedName);\n}\n\n/**\n * Determine the scoped name to use when pushing an unscoped package.\n */\nexport async function resolveScopedNameForPush(\n unscopedName: string,\n profileName?: string,\n prompt?: PromptPort\n): Promise<string> {\n if (isScopedName(unscopedName)) {\n throw new Error(`Expected unscoped name, received '${unscopedName}'`);\n }\n\n return await promptForNewScopedName(\n unscopedName,\n profileName,\n `Remote registry requires a scope. Enter a scoped name for '${unscopedName}' (format @scope/${unscopedName}):`,\n prompt\n );\n}\n\nexport async function resolveScopedNameForPushWithUserScope(\n unscopedName: string,\n username: string,\n profileName?: string,\n prompt?: PromptPort\n): Promise<string> {\n if (isScopedName(unscopedName)) {\n throw new Error(`Expected unscoped name, received '${unscopedName}'`);\n }\n\n if (!username?.trim()) {\n throw new Error('Username is required to apply default scope.');\n }\n\n const prm = prompt ?? resolvePrompt();\n const normalizedName = normalizePackageName(unscopedName);\n\n const choice = await prm.select<'default' | 'custom'>(\n `Package '${normalizedName}' must be scoped before pushing. Choose a scope:`,\n [\n {\n title: `Use default scope @${username}`,\n value: 'default' as const,\n description: `Renames to @${username}/${normalizedName}`\n },\n {\n title: 'Enter scope...',\n value: 'custom' as const,\n description: `Enter a custom scope for ${normalizedName}`\n }\n ],\n 'Use arrow keys to select, Enter to confirm'\n );\n\n if (!choice) {\n throw new UserCancellationError('Operation cancelled by user');\n }\n\n let scope = username;\n if (choice === 'custom') {\n const profileScope = await getDefaultScopeForProfile(profileName);\n const initialScope = profileScope?.replace(/^@/, '') || username;\n\n const enteredScope = await prm.text(\n `Enter a scope (without @) for '${normalizedName}':`,\n {\n initial: initialScope,\n validate: async (value: string) => {\n if (!value) return 'Scope is required';\n\n const candidate = buildScopedNameFromScope(normalizedName, value);\n try {\n await ensureScopedNameAvailable(candidate);\n return true;\n } catch (error) {\n return (error as Error).message;\n }\n }\n }\n );\n\n if (!enteredScope) {\n throw new UserCancellationError('Operation cancelled by user');\n }\n\n scope = enteredScope;\n }\n\n const scopedName = buildScopedNameFromScope(normalizedName, scope);\n await ensureScopedNameAvailable(scopedName);\n return scopedName;\n}\n\nexport interface SaveNameResolution {\n effectiveName: string;\n selectedExistingScopedName?: string;\n newScopedName?: string;\n nameChanged: boolean;\n}\n\n/**\n * Resolve which name should be used for a save invocation, prompting when needed.\n */\nexport async function resolveEffectiveNameForSave(\n inputName: string,\n profileName?: string,\n prompt?: PromptPort\n): Promise<SaveNameResolution> {\n const prm = prompt ?? resolvePrompt();\n const normalizedInput = normalizePackageName(inputName);\n\n if (isScopedName(normalizedInput)) {\n return {\n effectiveName: normalizedInput,\n nameChanged: false\n };\n }\n\n const scopedVariants = await findScopedVariantsInRegistry(normalizedInput);\n if (scopedVariants.length === 0) {\n return {\n effectiveName: normalizedInput,\n nameChanged: false\n };\n }\n\n const choice = await prm.select<string>(\n `Found scoped packages matching '${normalizedInput}'. How should this save proceed?`,\n [\n ...scopedVariants.map(variant => ({\n title: `Use existing scoped package ${variant}`,\n value: variant,\n description: `Treat this package as '${variant}'`\n })),\n {\n title: 'Create a new scoped name',\n value: '__create_new_scoped__',\n description: 'Create a brand new scoped identity (will prompt for name)'\n },\n {\n title: `Keep unscoped name '${normalizedInput}'`,\n value: '__keep_unscoped__',\n description: 'Continue saving as unscoped (push will still require scoping later)'\n }\n ],\n 'Use arrow keys to select, Enter to confirm'\n );\n\n if (!choice) {\n throw new UserCancellationError('Operation cancelled by user');\n }\n\n if (choice === '__keep_unscoped__') {\n return {\n effectiveName: normalizedInput,\n nameChanged: false\n };\n }\n\n if (choice === '__create_new_scoped__') {\n const newScopedName = await promptForNewScopedName(normalizedInput, profileName, undefined, prm);\n return {\n effectiveName: newScopedName,\n newScopedName,\n nameChanged: newScopedName !== normalizedInput\n };\n }\n\n const normalizedChoice = normalizePackageName(choice);\n return {\n effectiveName: normalizedChoice,\n selectedExistingScopedName: normalizedChoice,\n nameChanged: normalizedChoice !== normalizedInput\n };\n}\n\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAkDA,eAAe,mBAAmB,MAAgC;AAChE,MAAM,aAAa,qBAAqB,IAAI;AAC5C,SAAO,MAAM,OAAO,eAAe,UAAU,CAAC;AAChD;AAEA,SAAS,yBAAyB,cAAsB,OAAuB;AAC7E,MAAM,kBAAkB,qBAAqB,MAAM,QAAQ,MAAM,EAAE,CAAC,GAC9D,iBAAiB,qBAAqB,YAAY;AACxD,SAAO,IAAI,eAAe,IAAI,cAAc;AAC9C;AAEA,eAAe,0BAA0B,MAA6B;AACpE,MAAI;AACF,wBAAoB,IAAI;AAAA,EAC1B,SAAS,OAAO;AACd,UAAM,IAAI,MAAO,MAAgB,QAAQ,QAAQ,MAAM,IAAI,CAAC;AAAA,EAC9D;AAEA,MAAI,CAAC,aAAa,IAAI;AACpB,UAAM,IAAI,MAAM,wCAAwC;AAG1D,MAAI,MAAM,mBAAmB,IAAI;AAC/B,UAAM,IAAI;AAAA,MACR,YAAY,IAAI;AAAA,IAClB;AAEJ;AAKA,eAAsB,0BAA0B,aAAmD;AACjG,SAAK,eAIU,MAAM,cAAc,OAAO,GACb,WAAW,WAAW,GAC7B,UAAU,QAL9B;AAMJ;AA0EA,eAAsB,sCACpB,cACA,UACA,aACA,QACiB;AACjB,MAAI,aAAa,YAAY;AAC3B,UAAM,IAAI,MAAM,qCAAqC,YAAY,GAAG;AAGtE,MAAI,CAAC,UAAU,KAAK;AAClB,UAAM,IAAI,MAAM,8CAA8C;AAGhE,MAAM,MAAM,UAAU,cAAc,GAC9B,iBAAiB,qBAAqB,YAAY,GAElD,SAAS,MAAM,IAAI;AAAA,IACvB,YAAY,cAAc;AAAA,IAC1B;AAAA,MACE;AAAA,QACE,OAAO,sBAAsB,QAAQ;AAAA,QACrC,OAAO;AAAA,QACP,aAAa,eAAe,QAAQ,IAAI,cAAc;AAAA,MACxD;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,OAAO;AAAA,QACP,aAAa,4BAA4B,cAAc;AAAA,MACzD;AAAA,IACF;AAAA,IACA;AAAA,EACF;AAEA,MAAI,CAAC;AACH,UAAM,IAAI,sBAAsB,6BAA6B;AAG/D,MAAI,QAAQ;AACZ,MAAI,WAAW,UAAU;AAEvB,QAAM,gBADe,MAAM,0BAA0B,WAAW,IAC7B,QAAQ,MAAM,EAAE,KAAK,UAElD,eAAe,MAAM,IAAI;AAAA,MAC7B,kCAAkC,cAAc;AAAA,MAChD;AAAA,QACE,SAAS;AAAA,QACT,UAAU,OAAO,UAAkB;AACjC,cAAI,CAAC,MAAO,QAAO;AAEnB,cAAM,YAAY,yBAAyB,gBAAgB,KAAK;AAChE,cAAI;AACF,yBAAM,0BAA0B,SAAS,GAClC;AAAA,UACT,SAAS,OAAO;AACd,mBAAQ,MAAgB;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC;AACH,YAAM,IAAI,sBAAsB,6BAA6B;AAG/D,YAAQ;AAAA,EACV;AAEA,MAAM,aAAa,yBAAyB,gBAAgB,KAAK;AACjE,eAAM,0BAA0B,UAAU,GACnC;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
getPlatformDefinition
|
|
4
|
+
} from "./chunk-N43IXOND.js";
|
|
5
|
+
import {
|
|
6
|
+
FILE_PATTERNS,
|
|
7
|
+
PACKAGE_ROOT_DIRS
|
|
8
|
+
} from "./chunk-IHVZ5AUJ.js";
|
|
9
|
+
|
|
10
|
+
// ../core/src/core/platform/platform-root-files.ts
|
|
11
|
+
function getPlatformRootFileNames(platforms, targetDir) {
|
|
12
|
+
let names = /* @__PURE__ */ new Set([FILE_PATTERNS.AGENTS_MD]);
|
|
13
|
+
for (let platform of platforms) {
|
|
14
|
+
let def = getPlatformDefinition(platform, targetDir);
|
|
15
|
+
def.rootFile && names.add(def.rootFile);
|
|
16
|
+
}
|
|
17
|
+
return names;
|
|
18
|
+
}
|
|
19
|
+
function stripRootCopyPrefix(path) {
|
|
20
|
+
let prefix = `${PACKAGE_ROOT_DIRS.ROOT_COPY}/`;
|
|
21
|
+
if (path.startsWith(prefix)) {
|
|
22
|
+
let stripped = path.slice(prefix.length);
|
|
23
|
+
return stripped.length > 0 ? stripped : null;
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export {
|
|
29
|
+
getPlatformRootFileNames,
|
|
30
|
+
stripRootCopyPrefix
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=chunk-L5GRJQBS.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../core/src/core/platform/platform-root-files.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Platform Root Files Utilities\n * Shared utilities for collecting and working with platform root file names\n */\n\nimport { FILE_PATTERNS, PACKAGE_ROOT_DIRS } from '../../constants/index.js';\nimport type { Platform } from '../../types/platform.js';\nimport { getPlatformDefinition } from '../platforms.js';\n\n/**\n * Get all platform root file names (including universal AGENTS.md) for the given platforms.\n * @param platforms - Array of platforms to collect root files from\n * @param targetDir - Optional target directory for platform config overrides\n * @returns Set of root file names\n */\nexport function getPlatformRootFileNames(platforms: Platform[], targetDir?: string): Set<string> {\n const names = new Set<string>([FILE_PATTERNS.AGENTS_MD]);\n for (const platform of platforms) {\n const def = getPlatformDefinition(platform, targetDir);\n if (def.rootFile) {\n names.add(def.rootFile);\n }\n }\n return names;\n}\n\n/**\n * Strip the root copy prefix from a path if it starts with `root/`.\n * @param path - Path that may start with `root/`\n * @returns Path with `root/` prefix stripped, or original path if it doesn't start with `root/`\n */\nexport function stripRootCopyPrefix(path: string): string | null {\n const prefix = `${PACKAGE_ROOT_DIRS.ROOT_COPY}/`;\n if (path.startsWith(prefix)) {\n const stripped = path.slice(prefix.length);\n return stripped.length > 0 ? stripped : null;\n }\n return null;\n}\n\n/**\n * Check if a path is a root copy path (starts with `root/`).\n * @param path - Path to check\n * @returns True if path starts with `root/`\n */\nexport function isRootCopyPath(path: string): boolean {\n return path.startsWith(`${PACKAGE_ROOT_DIRS.ROOT_COPY}/`);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;AAeO,SAAS,yBAAyB,WAAuB,WAAiC;AAC/F,MAAM,QAAQ,oBAAI,IAAY,CAAC,cAAc,SAAS,CAAC;AACvD,WAAW,YAAY,WAAW;AAChC,QAAM,MAAM,sBAAsB,UAAU,SAAS;AACrD,IAAI,IAAI,YACN,MAAM,IAAI,IAAI,QAAQ;AAAA,EAE1B;AACA,SAAO;AACT;AAOO,SAAS,oBAAoB,MAA6B;AAC/D,MAAM,SAAS,GAAG,kBAAkB,SAAS;AAC7C,MAAI,KAAK,WAAW,MAAM,GAAG;AAC3B,QAAM,WAAW,KAAK,MAAM,OAAO,MAAM;AACzC,WAAO,SAAS,SAAS,IAAI,WAAW;AAAA,EAC1C;AACA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
extractPlatformSuffixFromFilename
|
|
4
|
+
} from "./chunk-4X2EJHJN.js";
|
|
5
|
+
import {
|
|
6
|
+
splitFrontmatter
|
|
7
|
+
} from "./chunk-VQ2KY6CK.js";
|
|
8
|
+
import {
|
|
9
|
+
getPlatformDefinitions,
|
|
10
|
+
isPlatformId,
|
|
11
|
+
matchesUniversalPattern,
|
|
12
|
+
resolveSwitchExpressionFull
|
|
13
|
+
} from "./chunk-N43IXOND.js";
|
|
14
|
+
import {
|
|
15
|
+
logger
|
|
16
|
+
} from "./chunk-5EFWGD33.js";
|
|
17
|
+
|
|
18
|
+
// ../core/src/core/install/file-format-detector.ts
|
|
19
|
+
import { minimatch } from "minimatch";
|
|
20
|
+
|
|
21
|
+
// ../core/src/core/install/schema-registry.ts
|
|
22
|
+
import { readFileSync, existsSync } from "fs";
|
|
23
|
+
import { join, dirname } from "path";
|
|
24
|
+
import { fileURLToPath } from "url";
|
|
25
|
+
function findProjectRoot() {
|
|
26
|
+
let __filename = fileURLToPath(import.meta.url), dir = dirname(__filename);
|
|
27
|
+
for (let i = 0; i < 10; i++) {
|
|
28
|
+
if (existsSync(join(dir, "platforms.jsonc")))
|
|
29
|
+
return dir;
|
|
30
|
+
let parent = dirname(dir);
|
|
31
|
+
if (parent === dir) break;
|
|
32
|
+
dir = parent;
|
|
33
|
+
}
|
|
34
|
+
return join(dirname(fileURLToPath(import.meta.url)), "../../../");
|
|
35
|
+
}
|
|
36
|
+
var projectRoot = findProjectRoot(), platformsJsoncPath = join(projectRoot, "platforms.jsonc"), SchemaRegistry = class {
|
|
37
|
+
constructor() {
|
|
38
|
+
this.schemaCache = /* @__PURE__ */ new Map();
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Load a schema from an explicit path
|
|
42
|
+
*
|
|
43
|
+
* @param schemaPath - Relative path from platforms.jsonc (e.g., "./schemas/formats/claude-agent.schema.json")
|
|
44
|
+
* @returns Parsed JSON schema with detection extensions
|
|
45
|
+
*/
|
|
46
|
+
loadSchema(schemaPath) {
|
|
47
|
+
if (this.schemaCache.has(schemaPath))
|
|
48
|
+
return this.schemaCache.get(schemaPath);
|
|
49
|
+
try {
|
|
50
|
+
let resolvedPath = this.resolveSchemaPath(schemaPath), content = readFileSync(resolvedPath, "utf-8"), schema = JSON.parse(content);
|
|
51
|
+
return !schema.$schema || !schema.properties ? (logger.warn(`Schema at ${schemaPath} is missing required fields ($schema, properties)`), null) : (this.schemaCache.set(schemaPath, schema), schema);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
return logger.warn(`Failed to load schema from ${schemaPath}:`, error), null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Resolve schema path relative to platforms.jsonc
|
|
58
|
+
*/
|
|
59
|
+
resolveSchemaPath(schemaPath) {
|
|
60
|
+
let cleanPath = schemaPath.replace(/^\.\//, "");
|
|
61
|
+
return join(dirname(platformsJsoncPath), cleanPath);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get schema for a flow's 'from' or 'to' pattern
|
|
65
|
+
*
|
|
66
|
+
* @param flow - Flow object (may use string or object patterns)
|
|
67
|
+
* @param direction - Which pattern to extract schema from ('from' or 'to')
|
|
68
|
+
* @param context - Optional flow context for resolving $switch expressions
|
|
69
|
+
* @returns Schema if pattern has schema reference, null otherwise
|
|
70
|
+
*/
|
|
71
|
+
getSchemaForFlow(flow, direction, context) {
|
|
72
|
+
let pattern = flow[direction];
|
|
73
|
+
if (typeof pattern == "object" && "$switch" in pattern) {
|
|
74
|
+
if (!context)
|
|
75
|
+
return null;
|
|
76
|
+
try {
|
|
77
|
+
let result = resolveSwitchExpressionFull(pattern, context);
|
|
78
|
+
return result.schema ? this.loadSchema(result.schema) : null;
|
|
79
|
+
} catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
let schemaPath = this.extractSchemaPath(pattern, direction);
|
|
84
|
+
return schemaPath ? this.loadSchema(schemaPath) : null;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Extract schema path from a pattern (string, array, or object)
|
|
88
|
+
*/
|
|
89
|
+
extractSchemaPath(pattern, direction) {
|
|
90
|
+
if (typeof pattern == "string")
|
|
91
|
+
return null;
|
|
92
|
+
if (Array.isArray(pattern) && direction === "from") {
|
|
93
|
+
if (pattern.length === 0) return null;
|
|
94
|
+
let first = pattern[0];
|
|
95
|
+
return typeof first == "object" && "schema" in first && first.schema || null;
|
|
96
|
+
}
|
|
97
|
+
return typeof pattern == "object" && pattern !== null && "schema" in pattern && pattern.schema || null;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get all schemas referenced in platform flows
|
|
101
|
+
*
|
|
102
|
+
* @param platforms - Platform definitions registry
|
|
103
|
+
* @returns Map of schema path -> loaded schema
|
|
104
|
+
*/
|
|
105
|
+
getAllFlowSchemas(platforms) {
|
|
106
|
+
let schemas = /* @__PURE__ */ new Map();
|
|
107
|
+
for (let [platformId, def] of Object.entries(platforms))
|
|
108
|
+
if (def.import && Array.isArray(def.import))
|
|
109
|
+
for (let flow of def.import) {
|
|
110
|
+
let schema = this.getSchemaForFlow(flow, "from");
|
|
111
|
+
if (schema) {
|
|
112
|
+
let schemaPath = this.extractSchemaPath(flow.from, "from");
|
|
113
|
+
schemaPath && schemas.set(schemaPath, schema);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return schemas;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Clear the schema cache
|
|
120
|
+
* Useful for testing or reloading schemas
|
|
121
|
+
*/
|
|
122
|
+
clearCache() {
|
|
123
|
+
this.schemaCache.clear();
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get number of cached schemas
|
|
127
|
+
*/
|
|
128
|
+
getCacheSize() {
|
|
129
|
+
return this.schemaCache.size;
|
|
130
|
+
}
|
|
131
|
+
}, schemaRegistry = new SchemaRegistry();
|
|
132
|
+
function getPatternFromFlow(flow, direction) {
|
|
133
|
+
let pattern = flow[direction];
|
|
134
|
+
if (typeof pattern == "object" && pattern !== null && "$switch" in pattern || typeof pattern == "object" && pattern !== null && !("pattern" in pattern) && !Array.isArray(pattern))
|
|
135
|
+
return null;
|
|
136
|
+
if (typeof pattern == "string")
|
|
137
|
+
return pattern;
|
|
138
|
+
if (Array.isArray(pattern) && direction === "from") {
|
|
139
|
+
if (pattern.length === 0) return null;
|
|
140
|
+
let first = pattern[0];
|
|
141
|
+
return typeof first == "string" ? first : typeof first == "object" && "pattern" in first ? first.pattern : null;
|
|
142
|
+
}
|
|
143
|
+
return typeof pattern == "object" && pattern !== null && "pattern" in pattern ? pattern.pattern : null;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// ../core/src/core/install/file-format-detector.ts
|
|
147
|
+
function detectFileFormat(file, targetDir) {
|
|
148
|
+
let frontmatter = file.frontmatter;
|
|
149
|
+
if (!frontmatter && file.content && (frontmatter = splitFrontmatter(file.content).frontmatter || {}), !frontmatter || Object.keys(frontmatter).length === 0) {
|
|
150
|
+
let normalizedPath = file.path.replace(/\\/g, "/").replace(/^\.\/?/, "");
|
|
151
|
+
return matchesUniversalPattern(normalizedPath, targetDir) ? {
|
|
152
|
+
platform: "universal",
|
|
153
|
+
confidence: 0.3,
|
|
154
|
+
matchedFlow: null,
|
|
155
|
+
matchedSchema: null,
|
|
156
|
+
matchedFields: [],
|
|
157
|
+
path: file.path
|
|
158
|
+
} : {
|
|
159
|
+
platform: "unknown",
|
|
160
|
+
confidence: 0,
|
|
161
|
+
matchedFlow: null,
|
|
162
|
+
matchedSchema: null,
|
|
163
|
+
matchedFields: [],
|
|
164
|
+
path: file.path
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
let platforms = getPlatformDefinitions(targetDir), matches = [];
|
|
168
|
+
for (let [platformId, def] of Object.entries(platforms)) {
|
|
169
|
+
if (def.export && def.export.length > 0)
|
|
170
|
+
for (let flow of def.export) {
|
|
171
|
+
let schema = schemaRegistry.getSchemaForFlow(flow, "to");
|
|
172
|
+
if (!schema) continue;
|
|
173
|
+
let match = scoreAgainstSchema(frontmatter, schema, flow, file.path, platformId);
|
|
174
|
+
match.score > 0 && matches.push(match);
|
|
175
|
+
}
|
|
176
|
+
if (def.import && def.import.length > 0)
|
|
177
|
+
for (let flow of def.import) {
|
|
178
|
+
let schema = schemaRegistry.getSchemaForFlow(flow, "from");
|
|
179
|
+
if (!schema) continue;
|
|
180
|
+
let match = scoreAgainstSchema(frontmatter, schema, flow, file.path, platformId);
|
|
181
|
+
match.score > 0 && matches.push(match);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (matches.length === 0) {
|
|
185
|
+
let pathPlatform = extractPlatformSuffixFromFilename(file.path);
|
|
186
|
+
return pathPlatform && isPlatformId(pathPlatform) ? {
|
|
187
|
+
platform: pathPlatform,
|
|
188
|
+
confidence: 0.7,
|
|
189
|
+
matchedFlow: null,
|
|
190
|
+
matchedSchema: null,
|
|
191
|
+
matchedFields: [],
|
|
192
|
+
path: file.path
|
|
193
|
+
} : {
|
|
194
|
+
platform: "universal",
|
|
195
|
+
confidence: 0.3,
|
|
196
|
+
matchedFlow: null,
|
|
197
|
+
matchedSchema: null,
|
|
198
|
+
matchedFields: [],
|
|
199
|
+
path: file.path
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
let bestMatch = matches.reduce(
|
|
203
|
+
(best, current) => current.score > best.score ? current : best
|
|
204
|
+
);
|
|
205
|
+
return {
|
|
206
|
+
platform: bestMatch.platform,
|
|
207
|
+
confidence: Math.min(1, bestMatch.score / bestMatch.maxScore),
|
|
208
|
+
matchedFlow: bestMatch.flow,
|
|
209
|
+
matchedSchema: bestMatch.schemaPath,
|
|
210
|
+
matchedFields: bestMatch.matchedFields,
|
|
211
|
+
path: file.path
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function scoreAgainstSchema(frontmatter, schema, flow, filePath, platformId) {
|
|
215
|
+
let score = 0, maxScore = 0, matchedFields = [];
|
|
216
|
+
if (schema.properties)
|
|
217
|
+
for (let [fieldName, property] of Object.entries(schema.properties)) {
|
|
218
|
+
let weight = property["x-detection-weight"] || 0.1;
|
|
219
|
+
if (maxScore += weight, !(fieldName in frontmatter))
|
|
220
|
+
continue;
|
|
221
|
+
let value = frontmatter[fieldName];
|
|
222
|
+
validateFieldAgainstSchema(value, property) && (score += weight, matchedFields.push(fieldName), property["x-exclusive"] && (score += 0.1));
|
|
223
|
+
}
|
|
224
|
+
let pathBoost = getPathBoost(filePath, flow);
|
|
225
|
+
score += pathBoost;
|
|
226
|
+
let schemaPath = extractSchemaPathFromFlow(flow);
|
|
227
|
+
return {
|
|
228
|
+
platform: platformId,
|
|
229
|
+
schemaPath: schemaPath || "unknown",
|
|
230
|
+
flow,
|
|
231
|
+
score,
|
|
232
|
+
maxScore,
|
|
233
|
+
matchedFields,
|
|
234
|
+
pathBoost
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
function validateFieldAgainstSchema(value, property) {
|
|
238
|
+
if (property.type) {
|
|
239
|
+
let types = Array.isArray(property.type) ? property.type : [property.type], valueType = getValueType(value);
|
|
240
|
+
if (!types.includes(valueType))
|
|
241
|
+
return !1;
|
|
242
|
+
}
|
|
243
|
+
if (property.enum && !property.enum.includes(value) || property.pattern && typeof value == "string" && !new RegExp(property.pattern).test(value))
|
|
244
|
+
return !1;
|
|
245
|
+
if (property.type === "array" && Array.isArray(value) && property.items && property.items.type) {
|
|
246
|
+
let itemType = property.items.type;
|
|
247
|
+
for (let item of value)
|
|
248
|
+
if (getValueType(item) !== itemType)
|
|
249
|
+
return !1;
|
|
250
|
+
}
|
|
251
|
+
return property.type === "object" && typeof value == "object" && value !== null, !0;
|
|
252
|
+
}
|
|
253
|
+
function getValueType(value) {
|
|
254
|
+
return value === null ? "null" : Array.isArray(value) ? "array" : typeof value;
|
|
255
|
+
}
|
|
256
|
+
function getPathBoost(filePath, flow) {
|
|
257
|
+
let pattern = getPatternFromFlow(flow, "from");
|
|
258
|
+
return pattern && matchGlob(filePath, pattern) ? 0.2 : 0;
|
|
259
|
+
}
|
|
260
|
+
function matchGlob(filePath, pattern) {
|
|
261
|
+
try {
|
|
262
|
+
return minimatch(filePath, pattern);
|
|
263
|
+
} catch (error) {
|
|
264
|
+
return logger.warn(`Invalid glob pattern: ${pattern}`, error), !1;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function extractSchemaPathFromFlow(flow) {
|
|
268
|
+
let from = flow.from;
|
|
269
|
+
if (typeof from == "object" && from !== null && "$switch" in from)
|
|
270
|
+
return null;
|
|
271
|
+
if (Array.isArray(from) && from.length > 0) {
|
|
272
|
+
let first = from[0];
|
|
273
|
+
return typeof first == "object" && "schema" in first && first.schema || null;
|
|
274
|
+
}
|
|
275
|
+
return typeof from == "object" && from !== null && "schema" in from && from.schema || null;
|
|
276
|
+
}
|
|
277
|
+
function detectFileFormats(files, targetDir) {
|
|
278
|
+
let results = /* @__PURE__ */ new Map();
|
|
279
|
+
for (let file of files) {
|
|
280
|
+
let format = detectFileFormat(file, targetDir);
|
|
281
|
+
results.set(file.path, format);
|
|
282
|
+
}
|
|
283
|
+
return results;
|
|
284
|
+
}
|
|
285
|
+
function groupFilesByFormat(formats) {
|
|
286
|
+
let groups = /* @__PURE__ */ new Map();
|
|
287
|
+
for (let [filePath, format] of formats) {
|
|
288
|
+
let platform = format.platform, group = groups.get(platform) || [];
|
|
289
|
+
group.push(filePath), groups.set(platform, group);
|
|
290
|
+
}
|
|
291
|
+
return groups;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export {
|
|
295
|
+
schemaRegistry,
|
|
296
|
+
getPatternFromFlow,
|
|
297
|
+
detectFileFormat,
|
|
298
|
+
scoreAgainstSchema,
|
|
299
|
+
detectFileFormats,
|
|
300
|
+
groupFilesByFormat
|
|
301
|
+
};
|
|
302
|
+
//# sourceMappingURL=chunk-LHEAUDJL.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../core/src/core/install/file-format-detector.ts", "../../core/src/core/install/schema-registry.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * File Format Detector Module\n * \n * Detects format for individual files using schema-based scoring.\n * Core detection logic for per-file format analysis.\n */\n\nimport { minimatch } from 'minimatch';\nimport { logger } from '../../utils/logger.js';\nimport { splitFrontmatter } from '../markdown-frontmatter.js';\nimport { schemaRegistry, getPatternFromFlow } from './schema-registry.js';\nimport { getPlatformDefinitions, isPlatformId, matchesUniversalPattern } from '../platforms.js';\nimport { extractPlatformSuffixFromFilename } from '../flows/platform-suffix-handler.js';\nimport type { Flow } from '../../types/flows.js';\nimport type { \n DetectionSchema,\n SchemaProperty,\n FileFormat,\n SchemaMatchResult,\n PackageFile,\n PlatformId\n} from './detection-types.js';\n\n/**\n * Detect format for a single file\n * \n * Main entry point for file-level format detection.\n * Scores file against all platform schemas and returns best match.\n * \n * @param file - Package file with path and optional content/frontmatter\n * @param targetDir - Optional target directory for local platform config\n * @returns Detected format with confidence score\n */\nexport function detectFileFormat(\n file: PackageFile,\n targetDir?: string\n): FileFormat {\n // Parse frontmatter if not already parsed\n let frontmatter = file.frontmatter;\n if (!frontmatter && file.content) {\n const parsed = splitFrontmatter(file.content);\n frontmatter = parsed.frontmatter || {};\n }\n \n // No frontmatter - use path-based fallback for universal locations\n if (!frontmatter || Object.keys(frontmatter).length === 0) {\n // Files at universal paths (commands/, agents/, rules/, etc.) or config files\n // are already in universal format; treat as universal, not unknown\n const normalizedPath = file.path.replace(/\\\\/g, '/').replace(/^\\.\\/?/, '');\n if (matchesUniversalPattern(normalizedPath, targetDir)) {\n return {\n platform: 'universal',\n confidence: 0.3,\n matchedFlow: null,\n matchedSchema: null,\n matchedFields: [],\n path: file.path\n };\n }\n return {\n platform: 'unknown',\n confidence: 0,\n matchedFlow: null,\n matchedSchema: null,\n matchedFields: [],\n path: file.path\n };\n }\n \n // Score against all platform schemas\n const platforms = getPlatformDefinitions(targetDir);\n const matches: SchemaMatchResult[] = [];\n \n for (const [platformId, def] of Object.entries(platforms)) {\n // Check both export and import flows for schemas\n // Export flows: universal -> platform (has platform schema on 'to')\n // Import flows: platform -> universal (has platform schema on 'from')\n \n // Check export flows for platform format schemas (on 'to' field)\n if (def.export && def.export.length > 0) {\n for (const flow of def.export) {\n const schema = schemaRegistry.getSchemaForFlow(flow, 'to');\n if (!schema) continue;\n \n const match = scoreAgainstSchema(frontmatter, schema, flow, file.path, platformId);\n if (match.score > 0) {\n matches.push(match);\n }\n }\n }\n \n // Check import flows for platform format schemas (on 'from' field)\n if (def.import && def.import.length > 0) {\n for (const flow of def.import) {\n const schema = schemaRegistry.getSchemaForFlow(flow, 'from');\n if (!schema) continue;\n \n const match = scoreAgainstSchema(frontmatter, schema, flow, file.path, platformId);\n if (match.score > 0) {\n matches.push(match);\n }\n }\n }\n }\n \n // No matches - use path-based platform suffix if present (e.g. foo.opencode.md)\n if (matches.length === 0) {\n const pathPlatform = extractPlatformSuffixFromFilename(file.path);\n if (pathPlatform && isPlatformId(pathPlatform)) {\n return {\n platform: pathPlatform,\n confidence: 0.7,\n matchedFlow: null,\n matchedSchema: null,\n matchedFields: [],\n path: file.path\n };\n }\n return {\n platform: 'universal',\n confidence: 0.3,\n matchedFlow: null,\n matchedSchema: null,\n matchedFields: [],\n path: file.path\n };\n }\n \n // Select best match\n const bestMatch = matches.reduce((best, current) => \n current.score > best.score ? current : best\n );\n \n return {\n platform: bestMatch.platform,\n confidence: Math.min(1.0, bestMatch.score / bestMatch.maxScore),\n matchedFlow: bestMatch.flow,\n matchedSchema: bestMatch.schemaPath,\n matchedFields: bestMatch.matchedFields,\n path: file.path\n };\n}\n\n/**\n * Score frontmatter against a schema\n * \n * Calculates confidence score based on:\n * - Field presence and type matching\n * - Detection weights from schema\n * - Exclusive field bonuses\n * - Path pattern matching boost\n * \n * @param frontmatter - Parsed frontmatter object\n * @param schema - Detection schema with x-detection-weight extensions\n * @param flow - Flow that references this schema\n * @param filePath - File path for pattern matching\n * @param platformId - Platform ID for result\n * @returns Schema match result with score breakdown\n */\nexport function scoreAgainstSchema(\n frontmatter: Record<string, any>,\n schema: DetectionSchema,\n flow: Flow,\n filePath: string,\n platformId: PlatformId\n): SchemaMatchResult {\n let score = 0;\n let maxScore = 0;\n const matchedFields: string[] = [];\n \n // Score each field\n if (schema.properties) {\n for (const [fieldName, property] of Object.entries(schema.properties)) {\n const weight = property['x-detection-weight'] || 0.1;\n maxScore += weight;\n \n // Check if field exists in frontmatter\n if (!(fieldName in frontmatter)) {\n continue;\n }\n \n const value = frontmatter[fieldName];\n \n // Validate against schema constraints\n if (!validateFieldAgainstSchema(value, property)) {\n continue;\n }\n \n // Field matches - add weight\n score += weight;\n matchedFields.push(fieldName);\n \n // Bonus for exclusive fields\n if (property['x-exclusive']) {\n score += 0.1;\n }\n }\n }\n \n // Add path boost if file matches flow pattern\n const pathBoost = getPathBoost(filePath, flow);\n score += pathBoost;\n \n // Extract schema path from flow\n const schemaPath = extractSchemaPathFromFlow(flow);\n \n return {\n platform: platformId,\n schemaPath: schemaPath || 'unknown',\n flow,\n score,\n maxScore,\n matchedFields,\n pathBoost\n };\n}\n\n/**\n * Validate a value against schema property constraints\n * \n * Checks type, enum, pattern, etc.\n */\nfunction validateFieldAgainstSchema(\n value: any,\n property: SchemaProperty\n): boolean {\n // Check type\n if (property.type) {\n const types = Array.isArray(property.type) ? property.type : [property.type];\n const valueType = getValueType(value);\n \n if (!types.includes(valueType)) {\n return false;\n }\n }\n \n // Check enum\n if (property.enum && !property.enum.includes(value)) {\n return false;\n }\n \n // Check pattern (for strings)\n if (property.pattern && typeof value === 'string') {\n const regex = new RegExp(property.pattern);\n if (!regex.test(value)) {\n return false;\n }\n }\n \n // Check array items\n if (property.type === 'array' && Array.isArray(value)) {\n if (property.items) {\n // Basic validation - all items should match item schema type\n if (property.items.type) {\n const itemType = property.items.type;\n for (const item of value) {\n if (getValueType(item) !== itemType) {\n return false;\n }\n }\n }\n }\n }\n \n // Check object properties\n if (property.type === 'object' && typeof value === 'object' && value !== null) {\n // Basic validation passed - could add more detailed object validation\n return true;\n }\n \n return true;\n}\n\n/**\n * Get JSON Schema type for a value\n */\nfunction getValueType(value: any): string {\n if (value === null) return 'null';\n if (Array.isArray(value)) return 'array';\n return typeof value;\n}\n\n/**\n * Get path boost for file matching flow pattern\n * \n * @param filePath - File path to check\n * @param flow - Flow with pattern\n * @returns Boost value (0-0.2)\n */\nfunction getPathBoost(filePath: string, flow: Flow): number {\n const pattern = getPatternFromFlow(flow, 'from');\n if (!pattern) {\n return 0;\n }\n \n // Check if file path matches pattern\n if (matchGlob(filePath, pattern)) {\n return 0.2;\n }\n \n return 0;\n}\n\n/**\n * Match file path against glob pattern\n */\nfunction matchGlob(filePath: string, pattern: string): boolean {\n try {\n return minimatch(filePath, pattern);\n } catch (error) {\n logger.warn(`Invalid glob pattern: ${pattern}`, error);\n return false;\n }\n}\n\n/**\n * Extract schema path from flow\n */\nfunction extractSchemaPathFromFlow(flow: Flow): string | null {\n const from = flow.from;\n \n // Skip switch expressions\n if (typeof from === 'object' && from !== null && '$switch' in from) {\n return null;\n }\n \n // Array - check first element\n if (Array.isArray(from) && from.length > 0) {\n const first = from[0];\n if (typeof first === 'object' && 'schema' in first) {\n return (first as any).schema || null;\n }\n return null;\n }\n \n // Object with schema\n if (typeof from === 'object' && from !== null && 'schema' in from) {\n return (from as any).schema || null;\n }\n \n return null;\n}\n\n/**\n * Batch detect formats for multiple files\n * \n * @param files - Array of package files\n * @param targetDir - Optional target directory\n * @returns Map of file path -> detected format\n */\nexport function detectFileFormats(\n files: PackageFile[],\n targetDir?: string\n): Map<string, FileFormat> {\n const results = new Map<string, FileFormat>();\n \n for (const file of files) {\n const format = detectFileFormat(file, targetDir);\n results.set(file.path, format);\n }\n \n return results;\n}\n\n/**\n * Group files by detected format\n * \n * @param formats - Map of file path -> format\n * @returns Map of platform -> file paths\n */\nexport function groupFilesByFormat(\n formats: Map<string, FileFormat>\n): Map<PlatformId | 'unknown', string[]> {\n const groups = new Map<PlatformId | 'unknown', string[]>();\n \n for (const [filePath, format] of formats) {\n const platform = format.platform;\n const group = groups.get(platform) || [];\n group.push(filePath);\n groups.set(platform, group);\n }\n \n return groups;\n}\n", "/**\n * Schema Registry Module\n * \n * Loads, caches, and provides access to format detection schemas.\n * Schemas are referenced from platforms.jsonc flows and define format-specific\n * field signatures for detection.\n */\n\nimport { readFileSync, existsSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { logger } from '../../utils/logger.js';\nimport type { Flow, FlowContext, SwitchExpression } from '../../types/flows.js';\nimport type { \n DetectionSchema, \n FlowPattern,\n PlatformId \n} from './detection-types.js';\nimport { resolveSwitchExpressionFull } from '../flows/switch-resolver.js';\n\n// Get the path to platforms.jsonc for resolving relative schema paths.\n// Walk up from __dirname until we find the file (mirrors getProjectRoot in jsonc.ts).\nfunction findProjectRoot(): string {\n const __filename = fileURLToPath(import.meta.url);\n let dir = dirname(__filename);\n for (let i = 0; i < 10; i++) {\n if (existsSync(join(dir, 'platforms.jsonc'))) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n // Fallback to original 3-levels-up behaviour\n return join(dirname(fileURLToPath(import.meta.url)), '../../../');\n}\n\nconst projectRoot = findProjectRoot();\nconst platformsJsoncPath = join(projectRoot, 'platforms.jsonc');\n\n/**\n * Schema Registry\n * \n * Singleton registry for loading and caching format detection schemas.\n * Schemas are lazy-loaded on first access and cached for reuse.\n */\nclass SchemaRegistry {\n private schemaCache = new Map<string, DetectionSchema>();\n\n /**\n * Load a schema from an explicit path\n * \n * @param schemaPath - Relative path from platforms.jsonc (e.g., \"./schemas/formats/claude-agent.schema.json\")\n * @returns Parsed JSON schema with detection extensions\n */\n loadSchema(schemaPath: string): DetectionSchema | null {\n // Check cache first\n if (this.schemaCache.has(schemaPath)) {\n return this.schemaCache.get(schemaPath)!;\n }\n\n try {\n // Resolve path relative to platforms.jsonc location\n const resolvedPath = this.resolveSchemaPath(schemaPath);\n \n const content = readFileSync(resolvedPath, 'utf-8');\n const schema = JSON.parse(content) as DetectionSchema;\n \n // Validate basic structure\n if (!schema.$schema || !schema.properties) {\n logger.warn(`Schema at ${schemaPath} is missing required fields ($schema, properties)`);\n return null;\n }\n \n // Cache and return\n this.schemaCache.set(schemaPath, schema);\n return schema;\n } catch (error) {\n logger.warn(`Failed to load schema from ${schemaPath}:`, error);\n return null;\n }\n }\n\n /**\n * Resolve schema path relative to platforms.jsonc\n */\n private resolveSchemaPath(schemaPath: string): string {\n // Remove leading \"./\" if present\n const cleanPath = schemaPath.replace(/^\\.\\//, '');\n return join(dirname(platformsJsoncPath), cleanPath);\n }\n\n /**\n * Get schema for a flow's 'from' or 'to' pattern\n * \n * @param flow - Flow object (may use string or object patterns)\n * @param direction - Which pattern to extract schema from ('from' or 'to')\n * @param context - Optional flow context for resolving $switch expressions\n * @returns Schema if pattern has schema reference, null otherwise\n */\n getSchemaForFlow(flow: Flow, direction: 'from' | 'to', context?: FlowContext): DetectionSchema | null {\n const pattern = flow[direction];\n \n // Handle switch expressions - resolve with context if available\n if (typeof pattern === 'object' && '$switch' in pattern) {\n if (!context) {\n // Without context, cannot resolve switch expression\n return null;\n }\n \n try {\n const result = resolveSwitchExpressionFull(pattern as SwitchExpression, context);\n if (result.schema) {\n return this.loadSchema(result.schema);\n }\n return null;\n } catch {\n // If switch resolution fails, return null\n return null;\n }\n }\n \n // Extract schema path from pattern\n const schemaPath = this.extractSchemaPath(pattern, direction);\n if (!schemaPath) {\n return null;\n }\n \n return this.loadSchema(schemaPath);\n }\n\n /**\n * Extract schema path from a pattern (string, array, or object)\n */\n private extractSchemaPath(\n pattern: string | string[] | FlowPattern | Record<string, any>,\n direction: 'from' | 'to'\n ): string | null {\n // String pattern - no schema\n if (typeof pattern === 'string') {\n return null;\n }\n \n // Array of patterns - check if first element has schema (for 'from' only)\n if (Array.isArray(pattern) && direction === 'from') {\n if (pattern.length === 0) return null;\n \n const first = pattern[0];\n if (typeof first === 'object' && 'schema' in first) {\n return (first as FlowPattern).schema || null;\n }\n return null;\n }\n \n // Object pattern - check for schema field\n if (typeof pattern === 'object' && pattern !== null && 'schema' in pattern) {\n return (pattern as FlowPattern).schema || null;\n }\n \n return null;\n }\n\n /**\n * Get all schemas referenced in platform flows\n * \n * @param platforms - Platform definitions registry\n * @returns Map of schema path -> loaded schema\n */\n getAllFlowSchemas(platforms: Record<PlatformId, any>): Map<string, DetectionSchema> {\n const schemas = new Map<string, DetectionSchema>();\n \n for (const [platformId, def] of Object.entries(platforms)) {\n // Process import flows (workspace -> package, used for detection)\n if (def.import && Array.isArray(def.import)) {\n for (const flow of def.import) {\n const schema = this.getSchemaForFlow(flow, 'from');\n if (schema) {\n const schemaPath = this.extractSchemaPath(flow.from, 'from');\n if (schemaPath) {\n schemas.set(schemaPath, schema);\n }\n }\n }\n }\n }\n \n return schemas;\n }\n\n /**\n * Clear the schema cache\n * Useful for testing or reloading schemas\n */\n clearCache(): void {\n this.schemaCache.clear();\n }\n\n /**\n * Get number of cached schemas\n */\n getCacheSize(): number {\n return this.schemaCache.size;\n }\n}\n\n// Export singleton instance\nexport const schemaRegistry = new SchemaRegistry();\n\n/**\n * Helper: Get pattern string from flow (handles string, array, and object formats)\n * \n * @param flow - Flow object\n * @param direction - Which pattern to extract ('from' or 'to')\n * @returns Pattern string (first pattern if array)\n */\nexport function getPatternFromFlow(flow: Flow, direction: 'from' | 'to'): string | null {\n const pattern = flow[direction];\n \n // Skip switch expressions\n if (typeof pattern === 'object' && pattern !== null && '$switch' in pattern) {\n return null;\n }\n \n // Skip MultiTargetFlows (can't extract single pattern)\n if (typeof pattern === 'object' && pattern !== null && !('pattern' in pattern) && !Array.isArray(pattern)) {\n return null;\n }\n \n // String pattern\n if (typeof pattern === 'string') {\n return pattern;\n }\n \n // Array of patterns (for 'from' only)\n if (Array.isArray(pattern) && direction === 'from') {\n if (pattern.length === 0) return null;\n \n const first = pattern[0];\n if (typeof first === 'string') {\n return first;\n }\n if (typeof first === 'object' && 'pattern' in first) {\n return (first as FlowPattern).pattern;\n }\n return null;\n }\n \n // Object pattern with 'pattern' field\n if (typeof pattern === 'object' && pattern !== null && 'pattern' in pattern) {\n return (pattern as unknown as FlowPattern).pattern;\n }\n \n return null;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
consoleOutput,
|
|
4
|
+
normalizePathWithTilde
|
|
5
|
+
} from "./chunk-RAKMX654.js";
|
|
6
|
+
|
|
7
|
+
// ../core/src/utils/formatters.ts
|
|
8
|
+
import { relative, isAbsolute } from "path";
|
|
9
|
+
function formatPathForDisplay(path, cwd = process.cwd()) {
|
|
10
|
+
if (path.startsWith("~") || !isAbsolute(path))
|
|
11
|
+
return path;
|
|
12
|
+
let relativePath = relative(cwd, path);
|
|
13
|
+
if (relativePath && !relativePath.startsWith(".."))
|
|
14
|
+
return relativePath;
|
|
15
|
+
let tildePath = normalizePathWithTilde(path);
|
|
16
|
+
return tildePath.startsWith("~") ? tildePath : path;
|
|
17
|
+
}
|
|
18
|
+
function getTreeConnector(isLast) {
|
|
19
|
+
return isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
20
|
+
}
|
|
21
|
+
function formatFileCount(count, type = "files") {
|
|
22
|
+
return `${count} ${count === 1 ? type.slice(0, -1) : type}`;
|
|
23
|
+
}
|
|
24
|
+
function formatFileSize(bytes) {
|
|
25
|
+
let mb = bytes / 1048576;
|
|
26
|
+
return mb >= 1 ? `${mb.toFixed(2)}MB` : `${(bytes / 1024).toFixed(2)}KB`;
|
|
27
|
+
}
|
|
28
|
+
function formatScopeTag(scope) {
|
|
29
|
+
return scope === "global" ? " [global]" : "";
|
|
30
|
+
}
|
|
31
|
+
function formatScopeBadge(scopes) {
|
|
32
|
+
return typeof scopes == "string" ? scopes === "global" ? "[global]" : "" : scopes.has("global") ? "[global]" : "";
|
|
33
|
+
}
|
|
34
|
+
function displayPackageConfig(packageConfig, path, isExisting = !1, output) {
|
|
35
|
+
let out = output ?? consoleOutput, action = isExisting ? "already exists" : "created", displayPath = formatPathForDisplay(path);
|
|
36
|
+
out.success(`${displayPath} ${action}`), out.message(` Name: ${packageConfig.name}`), packageConfig.version && out.message(` Version: ${packageConfig.version}`), packageConfig.description && out.message(` Description: ${packageConfig.description}`), packageConfig.keywords && packageConfig.keywords.length > 0 && out.message(` Keywords: ${packageConfig.keywords.join(", ")}`), packageConfig.private && out.message(" Private: Yes");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export {
|
|
40
|
+
formatPathForDisplay,
|
|
41
|
+
getTreeConnector,
|
|
42
|
+
formatFileCount,
|
|
43
|
+
formatFileSize,
|
|
44
|
+
formatScopeTag,
|
|
45
|
+
formatScopeBadge,
|
|
46
|
+
displayPackageConfig
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=chunk-MIURCESJ.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../core/src/utils/formatters.ts"],
|
|
4
|
+
"sourcesContent": ["import { PackageYml } from '../types/index.js';\nimport { relative, isAbsolute } from 'path';\nimport { normalizePathWithTilde } from './home-directory.js';\nimport type { OutputPort } from '../core/ports/output.js';\nimport { consoleOutput } from '../core/ports/console-output.js';\n\n/**\n * Formatting utilities for consistent display across commands\n */\n\n/**\n * Format a file system path for display to the user.\n * \n * This function provides a unified way to display paths across all commands:\n * - Uses tilde notation (~) for paths under home directory (e.g., ~/.claude/..., ~/.config/..., ~/.openpackage/...)\n * - Uses relative paths from cwd for paths in the workspace\n * - Falls back to absolute path for other cases\n * \n * @param path - The path to format (can be absolute or relative)\n * @param cwd - Current working directory (defaults to process.cwd())\n * @returns Formatted path string for display\n * \n * @example\n * formatPathForDisplay('/Users/user/.openpackage/packages/my-pkg') // => '~/.openpackage/packages/my-pkg'\n * formatPathForDisplay('/Users/user/.claude/agents/x.md') // => '~/.claude/agents/x.md'\n * formatPathForDisplay('/Users/user/workspace/file.txt', '/Users/user/workspace') // => 'file.txt'\n * formatPathForDisplay('./relative/path.txt') // => './relative/path.txt'\n */\nexport function formatPathForDisplay(path: string, cwd: string = process.cwd()): string {\n // If path is already in tilde notation, return as-is\n if (path.startsWith('~')) {\n return path;\n }\n \n // If path is relative, return as-is\n if (!isAbsolute(path)) {\n return path;\n }\n \n // Try relative path from cwd first (paths in workspace take precedence)\n const relativePath = relative(cwd, path);\n if (relativePath && !relativePath.startsWith('..')) {\n // Only use relative path if it's within cwd (doesn't start with ..)\n return relativePath;\n }\n \n // Use tilde notation for any path under home directory (~/.claude, ~/.config, ~/.cursor, ~/.openpackage, etc.)\n const tildePath = normalizePathWithTilde(path);\n if (tildePath.startsWith('~')) {\n return tildePath;\n }\n \n // Fall back to absolute path\n return path;\n}\n\n/**\n * Interface for package table entries\n */\nexport interface PackageTableEntry {\n name: string;\n version: string;\n description?: string;\n status?: string;\n type?: string;\n available?: string;\n}\n\n/**\n * Format and display an extended package table with status information (used by list command)\n */\nexport function displayExtendedPackageTable(packages: PackageTableEntry[], output?: OutputPort): void {\n const out = output ?? consoleOutput;\n if (packages.length === 0) {\n out.message('No packages found.');\n return;\n }\n \n // Table header\n out.message('FORMULA'.padEnd(20) + 'INSTALLED'.padEnd(12) + 'STATUS'.padEnd(15) + 'TYPE'.padEnd(15) + 'AVAILABLE');\n out.message('-------'.padEnd(20) + '---------'.padEnd(12) + '------'.padEnd(15) + '----'.padEnd(15) + '---------');\n \n // Display each package\n for (const pkg of packages) {\n const name = pkg.name.padEnd(20);\n const version = pkg.version.padEnd(12);\n const status = (pkg.status || '').padEnd(15);\n const type = (pkg.type || '').padEnd(15);\n const available = (pkg.available || '-').padEnd(9);\n \n out.message(`${name}${version}${status}${type}${available}`);\n }\n \n out.message('');\n out.message(`Total: ${packages.length} packages`);\n}\n\n/**\n * Generic table formatter for custom column layouts\n */\nexport function displayCustomTable<T>(\n items: T[],\n columns: Array<{\n header: string;\n width: number;\n accessor: (item: T) => string;\n }>,\n title?: string,\n output?: OutputPort\n): void {\n const out = output ?? consoleOutput;\n if (title) {\n out.message(title);\n out.message('');\n }\n \n if (items.length === 0) {\n out.message('No items found.');\n return;\n }\n \n // Build header\n const headerLine = columns.map(col => col.header.padEnd(col.width)).join('');\n const separatorLine = columns.map(col => '-'.repeat(col.header.length).padEnd(col.width)).join('');\n \n out.message(headerLine);\n out.message(separatorLine);\n \n // Display rows\n for (const item of items) {\n const row = columns.map(col => col.accessor(item).padEnd(col.width)).join('');\n out.message(row);\n }\n \n out.message('');\n out.message(`Total: ${items.length} items`);\n}\n\n/**\n * Format project summary line\n */\nexport function formatProjectSummary(name: string, version: string): string {\n return `${name}@${version}`;\n}\n\n/**\n * Format tree connector symbols\n */\nexport function getTreeConnector(isLast: boolean): string {\n return isLast ? '\u2514\u2500\u2500 ' : '\u251C\u2500\u2500 ';\n}\n\n/**\n * Format tree prefix for nested items\n */\nexport function getTreePrefix(prefix: string, isLast: boolean): string {\n return prefix + (isLast ? ' ' : '\u2502 ');\n}\n\n/**\n * Format status with appropriate emoji\n */\nexport function formatStatus(status: string): string {\n switch (status.toLowerCase()) {\n case 'installed':\n return '\u2705 installed';\n case 'missing':\n return '\u274C missing';\n case 'outdated':\n return '\u26A0\uFE0F outdated';\n case 'dependency-mismatch':\n return '\uD83D\uDD04 mismatch';\n default:\n return status;\n }\n}\n\n/**\n * Format file count with appropriate description\n */\nexport function formatFileCount(count: number, type: string = 'files'): string {\n return `${count} ${count === 1 ? type.slice(0, -1) : type}`;\n}\n\n/**\n * Format dependency list for display\n */\nexport function formatDependencyList(dependencies: Array<{ name: string; version: string }>): string[] {\n return dependencies.map(dep => `${dep.name}@${dep.version}`);\n}\n\n/**\n * Format file size in appropriate units (KB or MB)\n */\nexport function formatFileSize(bytes: number): string {\n const mb = bytes / (1024 * 1024);\n if (mb >= 1) {\n return `${mb.toFixed(2)}MB`;\n }\n const kb = bytes / 1024;\n return `${kb.toFixed(2)}KB`;\n}\n\n/**\n * Format a single scope as a tag.\n * Only [global] is shown \u2014 [project] is the default context and omitted to reduce noise.\n */\nexport function formatScopeTag(scope: string): string {\n return scope === 'global' ? ' [global]' : '';\n}\n\n/**\n * Format one or more scopes as a badge.\n * Only [global] is shown \u2014 [project] is the default context and omitted to reduce noise.\n */\nexport function formatScopeBadge(scopes: Set<string> | string): string {\n if (typeof scopes === 'string') {\n return scopes === 'global' ? '[global]' : '';\n }\n const hasGlobal = scopes.has('global');\n return hasGlobal ? '[global]' : '';\n}\n\n/**\n * Display package configuration details in a consistent format\n */\nexport function displayPackageConfig(packageConfig: PackageYml, path: string, isExisting: boolean = false, output?: OutputPort): void {\n const out = output ?? consoleOutput;\n const action = isExisting ? 'already exists' : 'created';\n const displayPath = formatPathForDisplay(path);\n \n out.success(`${displayPath} ${action}`);\n\n out.message(` Name: ${packageConfig.name}`);\n if (packageConfig.version) {\n out.message(` Version: ${packageConfig.version}`);\n }\n if (packageConfig.description) {\n out.message(` Description: ${packageConfig.description}`);\n }\n if (packageConfig.keywords && packageConfig.keywords.length > 0) {\n out.message(` Keywords: ${packageConfig.keywords.join(', ')}`);\n }\n if (packageConfig.private) {\n out.message(` Private: Yes`);\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;AACA,SAAS,UAAU,kBAAkB;AA2B9B,SAAS,qBAAqB,MAAc,MAAc,QAAQ,IAAI,GAAW;AAOtF,MALI,KAAK,WAAW,GAAG,KAKnB,CAAC,WAAW,IAAI;AAClB,WAAO;AAIT,MAAM,eAAe,SAAS,KAAK,IAAI;AACvC,MAAI,gBAAgB,CAAC,aAAa,WAAW,IAAI;AAE/C,WAAO;AAIT,MAAM,YAAY,uBAAuB,IAAI;AAC7C,SAAI,UAAU,WAAW,GAAG,IACnB,YAIF;AACT;AA8FO,SAAS,iBAAiB,QAAyB;AACxD,SAAO,SAAS,wBAAS;AAC3B;AA8BO,SAAS,gBAAgB,OAAe,OAAe,SAAiB;AAC7E,SAAO,GAAG,KAAK,IAAI,UAAU,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI,IAAI;AAC3D;AAYO,SAAS,eAAe,OAAuB;AACpD,MAAM,KAAK,QAAS;AACpB,SAAI,MAAM,IACD,GAAG,GAAG,QAAQ,CAAC,CAAC,OAGlB,IADI,QAAQ,MACN,QAAQ,CAAC,CAAC;AACzB;AAMO,SAAS,eAAe,OAAuB;AACpD,SAAO,UAAU,WAAW,cAAc;AAC5C;AAMO,SAAS,iBAAiB,QAAsC;AACrE,SAAI,OAAO,UAAW,WACb,WAAW,WAAW,aAAa,KAE1B,OAAO,IAAI,QAAQ,IAClB,aAAa;AAClC;AAKO,SAAS,qBAAqB,eAA2B,MAAc,aAAsB,IAAO,QAA2B;AACpI,MAAM,MAAM,UAAU,eAChB,SAAS,aAAa,mBAAmB,WACzC,cAAc,qBAAqB,IAAI;AAE7C,MAAI,QAAQ,GAAG,WAAW,IAAI,MAAM,EAAE,GAEtC,IAAI,QAAQ,WAAW,cAAc,IAAI,EAAE,GACvC,cAAc,WAChB,IAAI,QAAQ,cAAc,cAAc,OAAO,EAAE,GAE/C,cAAc,eAChB,IAAI,QAAQ,kBAAkB,cAAc,WAAW,EAAE,GAEvD,cAAc,YAAY,cAAc,SAAS,SAAS,KAC5D,IAAI,QAAQ,eAAe,cAAc,SAAS,KAAK,IAAI,CAAC,EAAE,GAE5D,cAAc,WAChB,IAAI,QAAQ,gBAAgB;AAEhC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|