@@ -18,6 +18,11 @@ import (
1818 "github.com/spf13/cobra"
1919)
2020
21+ const (
22+ // MaxExtensionSize is the maximum allowed size for extension bundles from API (50MB)
23+ MaxExtensionSize = 50 * 1024 * 1024
24+ )
25+
2126// ExtensionsService defines the subset of the Kernel SDK extension client that we use.
2227type ExtensionsService interface {
2328 List (ctx context.Context , opts ... option.RequestOption ) (res * []kernel.ExtensionListResponse , err error )
@@ -299,26 +304,6 @@ func (e ExtensionsCmd) Upload(ctx context.Context, in ExtensionsUploadInput) err
299304 pterm .Info .Println ("Analyzing extension directory..." )
300305 }
301306
302- estimatedSize , err := estimateExtensionSize (absDir )
303- if err != nil {
304- pterm .Warning .Printf ("Could not estimate size: %v\n " , err )
305- } else {
306- const maxSize = 50 * 1024 * 1024
307- if estimatedSize > maxSize {
308- pterm .Error .Printf ("Estimated bundle size (%s) exceeds limit (50MB)\n " ,
309- formatBytes (estimatedSize ))
310- pterm .Info .Println ("\n To reduce size:" )
311- pterm .Info .Println (" 1. Ensure node_modules/ is not needed (already excluded)" )
312- pterm .Info .Println (" 2. Remove large assets or documentation files" )
313- pterm .Info .Println (" 3. Build extension for production (minified)" )
314- return fmt .Errorf ("bundle would exceed maximum size" )
315- }
316-
317- if in .Output != "json" {
318- pterm .Info .Printf ("Estimated bundle size: %s\n " , formatBytes (estimatedSize ))
319- }
320- }
321-
322307 tmpFile := filepath .Join (os .TempDir (), fmt .Sprintf ("kernel_ext_%d.zip" , time .Now ().UnixNano ()))
323308
324309 if in .Output != "json" {
@@ -328,7 +313,6 @@ func (e ExtensionsCmd) Upload(ctx context.Context, in ExtensionsUploadInput) err
328313 // Use new extension-specific zip function
329314 stats , err := util .ZipExtensionDirectory (absDir , tmpFile , & util.ExtensionZipOptions {
330315 ExcludeDefaults : false , // Apply defaults
331- Verbose : false ,
332316 })
333317 if err != nil {
334318 pterm .Error .Println ("Failed to zip directory" )
@@ -339,7 +323,7 @@ func (e ExtensionsCmd) Upload(ctx context.Context, in ExtensionsUploadInput) err
339323 // Show helpful stats
340324 if in .Output != "json" {
341325 pterm .Success .Printf ("Created bundle: %s (%d files)\n " ,
342- formatBytes (stats .BytesIncluded ), stats .FilesIncluded )
326+ util . FormatBytes (stats .BytesIncluded ), stats .FilesIncluded )
343327 }
344328
345329 // Final size validation
@@ -348,10 +332,9 @@ func (e ExtensionsCmd) Upload(ctx context.Context, in ExtensionsUploadInput) err
348332 return fmt .Errorf ("failed to stat zip: %w" , err )
349333 }
350334
351- const maxSize = 50 * 1024 * 1024
352- if fileInfo .Size () > maxSize {
335+ if fileInfo .Size () > MaxExtensionSize {
353336 pterm .Error .Printf ("Extension bundle is too large: %s (max: 50MB)\n " ,
354- formatBytes (fileInfo .Size ()))
337+ util . FormatBytes (fileInfo .Size ()))
355338 pterm .Info .Println ("\n Suggestions to reduce size:" )
356339 pterm .Info .Println (" 1. Ensure you're building the extension for production" )
357340 pterm .Info .Println (" 2. Remove unnecessary assets (large images, videos)" )
@@ -399,62 +382,6 @@ func (e ExtensionsCmd) Upload(ctx context.Context, in ExtensionsUploadInput) err
399382 return nil
400383}
401384
402- // formatBytes formats bytes in a human-readable format
403- func formatBytes (bytes int64 ) string {
404- const unit = 1024
405- if bytes < unit {
406- return fmt .Sprintf ("%d B" , bytes )
407- }
408- div , exp := int64 (unit ), 0
409- for n := bytes / unit ; n >= unit ; n /= unit {
410- div *= unit
411- exp ++
412- }
413- return fmt .Sprintf ("%.1f %cB" , float64 (bytes )/ float64 (div ), "KMGTPE" [exp ])
414- }
415-
416- // estimateExtensionSize walks the directory and estimates the final zip size
417- // This provides fast feedback if the bundle will be too large
418- func estimateExtensionSize (srcDir string ) (int64 , error ) {
419- var totalSize int64
420- excludeMap := make (map [string ]bool )
421-
422- // Build exclusion map for fast lookup
423- for _ , pattern := range util .DefaultExtensionExclusions .ExcludeDirectory {
424- excludeMap [pattern ] = true
425- }
426-
427- err := filepath .Walk (srcDir , func (path string , info os.FileInfo , err error ) error {
428- if err != nil {
429- return err
430- }
431-
432- // Check if path should be excluded
433- if info .IsDir () {
434- if excludeMap [filepath .Base (path )] {
435- return filepath .SkipDir
436- }
437- return nil
438- }
439-
440- // Check against exact file names
441- base := filepath .Base (path )
442- // Check against file patterns
443- for _ , pattern := range util .DefaultExtensionExclusions .ExcludeFilenamePatterns {
444- if matched , _ := filepath .Match (pattern , base ); matched {
445- return nil
446- }
447- }
448-
449- totalSize += info .Size ()
450- return nil
451- })
452-
453- // Zip typically compresses 20-40% for code/text files
454- // Use conservative 30% compression estimate
455- return int64 (float64 (totalSize ) * 0.7 ), err
456- }
457-
458385// --- Cobra wiring ---
459386
460387var extensionsCmd = & cobra.Command {
0 commit comments