@@ -134,6 +134,7 @@ export function parseArgs(argv) {
134134 outputDir : "" ,
135135 outputName : "" ,
136136 packJson : "" ,
137+ pnpmPack : false ,
137138 skipBuild : false ,
138139 sourceDir : ROOT_DIR ,
139140 } ;
@@ -174,6 +175,8 @@ export function parseArgs(argv) {
174175 "packJson" ,
175176 readEqualsOptionValue ( arg . slice ( "--pack-json=" . length ) , "--pack-json" ) ,
176177 ) ;
178+ } else if ( arg === "--pnpm-pack" ) {
179+ setOnce ( arg , "pnpmPack" , true ) ;
177180 } else if ( arg === "--skip-build" ) {
178181 setOnce ( arg , "skipBuild" , true ) ;
179182 } else if ( arg === "--source-dir" ) {
@@ -192,6 +195,9 @@ export function parseArgs(argv) {
192195 if ( options . outputName ) {
193196 validateOutputName ( options . outputName ) ;
194197 }
198+ if ( options . packJson && options . pnpmPack ) {
199+ throw new Error ( "--pack-json cannot be combined with --pnpm-pack" ) ;
200+ }
195201 return options ;
196202}
197203
@@ -638,41 +644,45 @@ export async function packOpenClawPackageForDocker(sourceDir, outputDir, options
638644 const prepareChangelog = options . prepareChangelog ?? preparePackageChangelog ;
639645 const restoreChangelog = options . restoreChangelog ?? restorePackageChangelog ;
640646 const prepareBundledAiRuntime = options . prepareBundledAiRuntime ?? prepareBundledAiRuntimePackage ;
647+ const packTool = options . pnpmPack ? "pnpm" : "npm" ;
648+ if ( options . packJsonPath && options . pnpmPack ) {
649+ throw new Error ( "packJsonPath cannot be combined with pnpmPack" ) ;
650+ }
641651 console . error ( "==> Packing OpenClaw package" ) ;
642652 await prepareChangelog ( sourceDir ) ;
643653 let packOutput ;
644654 let cleanupBundledAiRuntime = async ( ) => { } ;
645655 try {
646656 await cleanPackedOpenClawTarballs ( outputDir ) ;
647657 cleanupBundledAiRuntime = await prepareBundledAiRuntime ( sourceDir , outputDir , runCaptureImpl ) ;
648- const packArgs = [
649- "pack" ,
650- ...( options . packJsonPath ? [ "--json" ] : [ ] ) ,
651- "--silent" ,
652- "--ignore-scripts" ,
653- "--pack-destination" ,
654- outputDir ,
655- ] ;
656- packOutput = await runCaptureImpl (
657- "npm" ,
658- packArgs ,
659- sourceDir ,
660- {
661- deferForwardedSignalExit : true ,
662- timeoutMs : resolveTimeoutMs (
663- "OPENCLAW_DOCKER_PACKAGE_PACK_TIMEOUT_MS" ,
664- DEFAULT_PACKAGE_PACK_TIMEOUT_MS ,
665- ) ,
666- } ,
667- ) ;
658+ const packArgs =
659+ packTool === "pnpm"
660+ ? [ "pack" , "--silent" , "--config.ignore-scripts=true" , "--pack-destination" , outputDir ]
661+ : [
662+ "pack" ,
663+ ...( options . packJsonPath ? [ "--json" ] : [ ] ) ,
664+ "--silent" ,
665+ "--ignore-scripts" ,
666+ "--pack-destination" ,
667+ outputDir ,
668+ ] ;
669+ packOutput = await runCaptureImpl ( packTool , packArgs , sourceDir , {
670+ deferForwardedSignalExit : true ,
671+ timeoutMs : resolveTimeoutMs (
672+ "OPENCLAW_DOCKER_PACKAGE_PACK_TIMEOUT_MS" ,
673+ DEFAULT_PACKAGE_PACK_TIMEOUT_MS ,
674+ ) ,
675+ } ) ;
668676 } finally {
669677 try {
670678 await cleanupBundledAiRuntime ( ) ;
671679 } finally {
672680 await restoreChangelog ( sourceDir ) ;
673681 }
674682 }
675- let tarball = await newestOpenClawTarball ( outputDir , packOutput ) ;
683+ // pnpm reports an absolute destination path. The directory was emptied before packing,
684+ // so scan that controlled destination instead of accepting a path from command output.
685+ let tarball = await newestOpenClawTarball ( outputDir , options . pnpmPack ? "" : packOutput ) ;
676686 if ( options . outputName ) {
677687 const target = path . join ( outputDir , options . outputName ) ;
678688 if ( target !== tarball ) {
@@ -720,6 +730,7 @@ async function main() {
720730 const tarball = await packOpenClawPackageForDocker ( sourceDir , outputDir , {
721731 outputName : options . outputName ,
722732 packJsonPath : options . packJson ,
733+ pnpmPack : options . pnpmPack ,
723734 } ) ;
724735
725736 console . error ( "==> Checking OpenClaw package tarball" ) ;
0 commit comments