@skaile/workspaces 1.6.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/{asset-feeds-PTZBWJEL.js → asset-feeds-Y66NCOQZ.js} +4 -4
  3. package/dist/{asset-feeds-PTZBWJEL.js.map → asset-feeds-Y66NCOQZ.js.map} +1 -1
  4. package/dist/asset-manager/index.js +1 -1
  5. package/dist/asset-manager/src/index.d.ts.map +1 -1
  6. package/dist/{chunk-NTYCGPZ3.js → chunk-7VGRRH2L.js} +6 -6
  7. package/dist/{chunk-NTYCGPZ3.js.map → chunk-7VGRRH2L.js.map} +1 -1
  8. package/dist/{chunk-EA73UA42.js → chunk-BSXBOKL6.js} +2 -2
  9. package/dist/{chunk-EA73UA42.js.map → chunk-BSXBOKL6.js.map} +1 -1
  10. package/dist/{chunk-Y5B5272E.js → chunk-MB6563TL.js} +16 -3
  11. package/dist/chunk-MB6563TL.js.map +1 -0
  12. package/dist/{chunk-SH55Z5QA.js → chunk-O3D4KYFG.js} +3 -3
  13. package/dist/{chunk-SH55Z5QA.js.map → chunk-O3D4KYFG.js.map} +1 -1
  14. package/dist/{chunk-SNN6O7ON.js → chunk-PP2LOT4W.js} +43 -7
  15. package/dist/chunk-PP2LOT4W.js.map +1 -0
  16. package/dist/{chunk-HIATVS2E.js → chunk-SZY7X4M2.js} +3 -3
  17. package/dist/{chunk-HIATVS2E.js.map → chunk-SZY7X4M2.js.map} +1 -1
  18. package/dist/{chunk-M4UKIJ5K.js → chunk-TC3GLA5D.js} +28 -13
  19. package/dist/chunk-TC3GLA5D.js.map +1 -0
  20. package/dist/{chunk-X7G2CCW4.js → chunk-TITPPC54.js} +3 -3
  21. package/dist/{chunk-X7G2CCW4.js.map → chunk-TITPPC54.js.map} +1 -1
  22. package/dist/{chunk-NRWDQBZ7.js → chunk-VBRXFLIP.js} +3 -3
  23. package/dist/{chunk-NRWDQBZ7.js.map → chunk-VBRXFLIP.js.map} +1 -1
  24. package/dist/{chunk-MY7TSVO7.js → chunk-Y3UCU4ZK.js} +6 -2
  25. package/dist/chunk-Y3UCU4ZK.js.map +1 -0
  26. package/dist/{chunk-OJ7G56I7.js → chunk-Y6FV73IH.js} +57 -3
  27. package/dist/chunk-Y6FV73IH.js.map +1 -0
  28. package/dist/cli/index.js +69 -40
  29. package/dist/cli/index.js.map +1 -1
  30. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  31. package/dist/cli/src/commands/library-index.d.ts +12 -2
  32. package/dist/cli/src/commands/library-index.d.ts.map +1 -1
  33. package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
  34. package/dist/cli/src/commands/manage.d.ts.map +1 -1
  35. package/dist/cli/src/commands/publish-core.d.ts +24 -0
  36. package/dist/cli/src/commands/publish-core.d.ts.map +1 -1
  37. package/dist/cli/src/commands/session-logs/remote-query.d.ts.map +1 -1
  38. package/dist/cli/src/commands/session-logs/remote-tail.d.ts.map +1 -1
  39. package/dist/cli/src/commands/session-logs/superjson-transformer.d.ts +12 -0
  40. package/dist/cli/src/commands/session-logs/superjson-transformer.d.ts.map +1 -0
  41. package/dist/cli/src/commands/source-manifest-publish.d.ts.map +1 -1
  42. package/dist/cli/src/commands/store.d.ts.map +1 -1
  43. package/dist/cli/src/store-auth.d.ts +11 -0
  44. package/dist/cli/src/store-auth.d.ts.map +1 -1
  45. package/dist/cli/src/store-publisher.d.ts +24 -1
  46. package/dist/cli/src/store-publisher.d.ts.map +1 -1
  47. package/dist/connectors/config.js +1 -1
  48. package/dist/connectors/index.js +2 -2
  49. package/dist/connectors/src/config.d.ts +21 -0
  50. package/dist/connectors/src/config.d.ts.map +1 -1
  51. package/dist/connectors/src/index.d.ts +1 -1
  52. package/dist/connectors/src/index.d.ts.map +1 -1
  53. package/dist/{ensure-sources-ORACQA4I.js → ensure-sources-NXBYK5GP.js} +4 -4
  54. package/dist/{ensure-sources-ORACQA4I.js.map → ensure-sources-NXBYK5GP.js.map} +1 -1
  55. package/dist/factory-assets/connectors/box.js +2 -2
  56. package/dist/factory-assets/connectors/deploy.js +2 -2
  57. package/dist/factory-assets/connectors/devserver.js +2 -2
  58. package/dist/factory-assets/connectors/flow/adapter.js +2 -2
  59. package/dist/factory-assets/connectors/flow/run-flow.js +3 -3
  60. package/dist/factory-assets/connectors/flow.js +2 -2
  61. package/dist/factory-assets/connectors/git.js +2 -2
  62. package/dist/factory-assets/connectors/gmail.js +2 -2
  63. package/dist/factory-assets/connectors/googledrive.js +2 -2
  64. package/dist/factory-assets/connectors/local.js +2 -2
  65. package/dist/factory-assets/connectors/mattermost.js +2 -2
  66. package/dist/factory-assets/connectors/memory.js +2 -2
  67. package/dist/factory-assets/connectors/minio.js +2 -2
  68. package/dist/factory-assets/connectors/postgres.js +2 -2
  69. package/dist/factory-assets/connectors/s3.js +2 -2
  70. package/dist/factory-assets/connectors/sharepoint.js +2 -2
  71. package/dist/factory-assets/connectors/sqlite.js +2 -2
  72. package/dist/factory-assets/connectors/static-server.js +2 -2
  73. package/dist/factory-assets/connectors/tunnel.js +2 -2
  74. package/dist/factory-assets/connectors/webdav.js +2 -2
  75. package/dist/factory-assets/connectors/xstate-store.js +2 -2
  76. package/dist/factory-assets/connectors/xstate.js +2 -2
  77. package/dist/{helpers-SXGIHFCF.js → helpers-DN4MWOHB.js} +4 -4
  78. package/dist/{helpers-SXGIHFCF.js.map → helpers-DN4MWOHB.js.map} +1 -1
  79. package/dist/{library-publish-NQQFPOUY.js → library-publish-TPWFSO3Q.js} +24 -8
  80. package/dist/library-publish-TPWFSO3Q.js.map +1 -0
  81. package/dist/{open-library-ODW2PJ2J.js → open-library-ST2VFQTK.js} +5 -5
  82. package/dist/{open-library-ODW2PJ2J.js.map → open-library-ST2VFQTK.js.map} +1 -1
  83. package/dist/runner/index.js +4 -4
  84. package/dist/runner/src/resources.d.ts +8 -2
  85. package/dist/runner/src/resources.d.ts.map +1 -1
  86. package/dist/runner/src/serve.d.ts.map +1 -1
  87. package/dist/runner/src/session-builder.d.ts +10 -0
  88. package/dist/runner/src/session-builder.d.ts.map +1 -1
  89. package/dist/sdk/asset-manager.js +1 -1
  90. package/dist/sdk/index.js +4 -4
  91. package/dist/sdk/runner.js +4 -4
  92. package/dist/{source-KPH66TXY.js → source-R4TWF424.js} +6 -6
  93. package/dist/{source-KPH66TXY.js.map → source-R4TWF424.js.map} +1 -1
  94. package/dist/{source-manifest-publish-HJ5G4CTH.js → source-manifest-publish-FXDK2BCI.js} +12 -10
  95. package/dist/source-manifest-publish-FXDK2BCI.js.map +1 -0
  96. package/dist/tui/index.js +4 -4
  97. package/dist/workspace-plugin/index.js +1 -1
  98. package/package.json +1 -1
  99. package/dist/chunk-M4UKIJ5K.js.map +0 -1
  100. package/dist/chunk-MY7TSVO7.js.map +0 -1
  101. package/dist/chunk-OJ7G56I7.js.map +0 -1
  102. package/dist/chunk-SNN6O7ON.js.map +0 -1
  103. package/dist/chunk-Y5B5272E.js.map +0 -1
  104. package/dist/library-publish-NQQFPOUY.js.map +0 -1
  105. package/dist/source-manifest-publish-HJ5G4CTH.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../cli/src/store-auth.ts","../cli/src/store-client.ts"],"names":["readFileSync"],"mappings":";;;;;;AAsBA,SAAS,YAAA,GAAwD;AAC/D,EAAA,MAAM,QAAA,GAAW,WAAA,CAAY,EAAE,CAAA,CAAE,SAAS,WAAW,CAAA;AACrD,EAAA,MAAM,SAAA,GAAY,WAAW,QAAQ,CAAA,CAAE,OAAO,QAAQ,CAAA,CAAE,OAAO,WAAW,CAAA;AAC1E,EAAA,OAAO,EAAE,UAAU,SAAA,EAAU;AAC/B;AAUA,SAAS,kBAAkB,GAAA,EAAqB;AAC9C,EAAA,OAAO,GAAA,CAAI,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAC/B;AAQO,SAAS,mBAAA,GAAuC;AACrD,EAAA,MAAM,OAAO,OAAA,CAAQ,GAAA,CAAI,eAAe,IAAA,CAAK,OAAA,IAAW,SAAS,CAAA;AACjE,EAAA,OAAO;AAAA,IACL,WAAA,EAAa,iBAAA,CAAkB,OAAA,CAAQ,GAAA,CAAI,uBAAuB,wBAAwB,CAAA;AAAA,IAC1F,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,kBAAA,IAAsB,cAAA;AAAA,IACzC,QAAA,EAAU,OAAA,CAAQ,GAAA,CAAI,uBAAA,IAA2B,kBAAA;AAAA,IACjD,UAAU,OAAA,CAAQ,GAAA,CAAI,gBAAA,IAAoB,IAAA,CAAK,MAAM,WAAW;AAAA,GAClE;AACF;AAGA,SAAS,KAAK,MAAA,EAAgE;AAC5E,EAAA,MAAM,OAAO,CAAA,EAAG,MAAA,CAAO,WAAW,CAAA,QAAA,EAAW,OAAO,KAAK,CAAA,wBAAA,CAAA;AACzD,EAAA,OAAO,EAAE,YAAY,CAAA,EAAG,IAAI,gBAAgB,KAAA,EAAO,CAAA,EAAG,IAAI,CAAA,MAAA,CAAA,EAAS;AACrE;AA2BA,IAAM,gBAAA,GAAmB,GAAA;AAUzB,SAAS,SAAS,MAAA,EAA4C;AAC5D,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,IAAA,CAAK,KAAA,CAAM,aAAa,MAAA,CAAO,QAAA,EAAU,OAAO,CAAC,CAAA;AAEhE,IAAA,IAAI,MAAA,IAAU,OAAO,MAAA,CAAO,YAAA,KAAiB,UAAU,OAAO,MAAA;AAC9D,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,SAAS,SAAA,CAAU,QAAyB,IAAA,EAAwB;AAClE,EAAA,SAAA,CAAU,QAAQ,MAAA,CAAO,QAAQ,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AACvD,EAAA,aAAA,CAAc,MAAA,CAAO,QAAA,EAAU,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,IAAA,EAAM,CAAC,CAAA,EAAG,EAAE,IAAA,EAAM,GAAA,EAAO,CAAA;AAC7E,EAAA,SAAA,CAAU,MAAA,CAAO,UAAU,GAAK,CAAA;AAClC;AAGO,SAAS,OAAO,MAAA,EAA+B;AACpD,EAAA,IAAI;AACF,IAAA,MAAA,CAAO,OAAO,QAAQ,CAAA;AAAA,EACxB,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAGO,SAAS,cAAc,MAAA,EAAkC;AAC9D,EAAA,OAAO,QAAA,CAAS,MAAM,CAAA,KAAM,IAAA;AAC9B;AAEA,SAAS,cAAc,KAAA,EAAkC;AACvD,EAAA,OAAO;AAAA,IACL,cAAc,KAAA,CAAM,YAAA;AAAA,IACpB,eAAe,KAAA,CAAM,aAAA;AAAA,IACrB,YAAY,IAAA,CAAK,GAAA,MAAS,KAAA,CAAM,UAAA,IAAc,OAAO,GAAA,GAAO;AAAA,GAC9D;AACF;AAEA,IAAM,YAAA,GAAe,CAAC,EAAA,KAA8B,IAAI,OAAA,CAAQ,CAAC,CAAA,KAAM,UAAA,CAAW,CAAA,EAAG,EAAE,CAAC,CAAA;AAExF,SAAS,aAAA,CAAc,KAAa,QAAA,EAAwB;AAC1D,EAAA,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,IACb;AAAA;;AAAA,IAAA,EAA8B,GAAG;;AAAA,oBAAA,EAA2B,QAAQ;;AAAA;AAAA;AAAA,GACtE;AACF;AAMA,eAAsB,WAAA,CACpB,MAAA,EACA,IAAA,GAAiB,EAAC,EACG;AACrB,EAAA,MAAM,SAAA,GAAY,KAAK,SAAA,IAAa,KAAA;AACpC,EAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,YAAA;AAC5B,EAAA,MAAM,QAAA,GAAW,KAAK,QAAA,IAAY,aAAA;AAClC,EAAA,MAAM,SAAA,GAAY,KAAK,MAAM,CAAA;AAC7B,EAAA,MAAM,OAAO,YAAA,EAAa;AAE1B,EAAA,MAAM,SAAA,GAAY,MAAM,SAAA,CAAU,SAAA,CAAU,UAAA,EAAY;AAAA,IACtD,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,IAC/D,IAAA,EAAM,IAAI,eAAA,CAAgB;AAAA,MACxB,WAAW,MAAA,CAAO,QAAA;AAAA,MAClB,KAAA,EAAO,gBAAA;AAAA,MACP,gBAAgB,IAAA,CAAK,SAAA;AAAA,MACrB,qBAAA,EAAuB;AAAA,KACxB;AAAA,GACF,CAAA;AACD,EAAA,IAAI,CAAC,UAAU,EAAA,EAAI;AACjB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,wCAAwC,SAAA,CAAU,MAAM,MAAM,MAAM,SAAA,CAAU,MAAM,CAAA;AAAA,KACtF;AAAA,EACF;AACA,EAAA,MAAM,MAAA,GAAU,MAAM,SAAA,CAAU,IAAA,EAAK;AAErC,EAAA,QAAA,CAAS,MAAA,CAAO,yBAAA,IAA6B,MAAA,CAAO,gBAAA,EAAkB,OAAO,SAAS,CAAA;AAEtF,EAAA,MAAM,UAAA,GAAA,CAAc,MAAA,CAAO,QAAA,IAAY,CAAA,IAAK,GAAA;AAC5C,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,OAAO,UAAA,GAAa,GAAA;AAClD,EAAA,IAAI,MAAA,GAAS,UAAA;AAEb,EAAA,OAAO,IAAA,CAAK,GAAA,EAAI,GAAI,QAAA,EAAU;AAC5B,IAAA,MAAM,MAAM,MAAM,CAAA;AAClB,IAAA,MAAM,QAAA,GAAW,MAAM,SAAA,CAAU,SAAA,CAAU,KAAA,EAAO;AAAA,MAChD,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,MAC/D,IAAA,EAAM,IAAI,eAAA,CAAgB;AAAA,QACxB,UAAA,EAAY,8CAAA;AAAA,QACZ,aAAa,MAAA,CAAO,WAAA;AAAA,QACpB,WAAW,MAAA,CAAO,QAAA;AAAA,QAClB,eAAe,IAAA,CAAK;AAAA,OACrB;AAAA,KACF,CAAA;AACD,IAAA,MAAM,KAAA,GAAS,MAAM,QAAA,CAAS,IAAA,EAAK;AACnC,IAAA,IAAI,SAAS,EAAA,EAAI;AACf,MAAA,MAAM,MAAA,GAAS,cAAc,KAAK,CAAA;AAClC,MAAA,SAAA,CAAU,QAAQ,MAAM,CAAA;AACxB,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,IAAI,KAAA,CAAM,UAAU,uBAAA,EAAyB;AAC7C,IAAA,IAAI,KAAA,CAAM,UAAU,WAAA,EAAa;AAC/B,MAAA,MAAA,IAAU,GAAA;AACV,MAAA;AAAA,IACF;AACA,IAAA,MAAM,IAAI,MAAM,CAAA,gBAAA,EAAmB,KAAA,CAAM,qBAAqB,KAAA,CAAM,KAAA,IAAS,eAAe,CAAA,CAAE,CAAA;AAAA,EAChG;AACA,EAAA,MAAM,IAAI,MAAM,oCAAoC,CAAA;AACtD;AAGA,eAAe,OAAA,CACb,MAAA,EACA,YAAA,EACA,SAAA,EACqB;AACrB,EAAA,MAAM,MAAM,MAAM,SAAA,CAAU,IAAA,CAAK,MAAM,EAAE,KAAA,EAAO;AAAA,IAC9C,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,IAC/D,IAAA,EAAM,IAAI,eAAA,CAAgB;AAAA,MACxB,UAAA,EAAY,eAAA;AAAA,MACZ,aAAA,EAAe,YAAA;AAAA,MACf,WAAW,MAAA,CAAO;AAAA,KACnB;AAAA,GACF,CAAA;AACD,EAAA,MAAM,KAAA,GAAS,MAAM,GAAA,CAAI,IAAA,EAAK;AAC9B,EAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,yBAAyB,KAAA,CAAM,iBAAA,IAAqB,KAAA,CAAM,KAAA,IAAS,IAAI,MAAM,CAAA;AAAA,KAC/E;AAAA,EACF;AACA,EAAA,MAAM,MAAA,GAAS,cAAc,KAAK,CAAA;AAClC,EAAA,SAAA,CAAU,QAAQ,MAAM,CAAA;AACxB,EAAA,OAAO,MAAA;AACT;AAMA,eAAsB,cAAA,CACpB,MAAA,EACA,IAAA,GAAiB,EAAC,EACD;AACjB,EAAA,MAAM,SAAA,GAAY,KAAK,SAAA,IAAa,KAAA;AACpC,EAAA,MAAM,IAAA,GAAO,SAAS,MAAM,CAAA;AAC5B,EAAA,IAAI,CAAC,IAAA,EAAM,MAAM,IAAI,MAAM,gDAAgD,CAAA;AAC3E,EAAA,IAAI,KAAK,GAAA,EAAI,GAAI,IAAA,CAAK,UAAA,SAAmB,IAAA,CAAK,YAAA;AAC9C,EAAA,IAAI,CAAC,IAAA,CAAK,aAAA,EAAe,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAC3F,EAAA,IAAI;AACF,IAAA,OAAA,CAAQ,MAAM,OAAA,CAAQ,MAAA,EAAQ,IAAA,CAAK,aAAA,EAAe,SAAS,CAAA,EAAG,YAAA;AAAA,EAChE,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,MAAM,qEAAqE,CAAA;AAAA,EACvF;AACF;;;ACvOO,SAAS,cAAA,GAA8B;AAC5C,EAAA,MAAM,eAAe,kBAAA,EAAmB;AACxC,EAAA,IAAI,WAAgC,EAAC;AACrC,EAAA,IAAI,UAAA,CAAW,YAAY,CAAA,EAAG;AAC5B,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,gBAAgB,IAAA,CAAK,KAAA,CAAMA,aAAa,YAAA,EAAc,OAAO,CAAC,CAAC,CAAA;AAAA,IAC5E,CAAA,CAAA,MAAQ;AACN,MAAA,QAAA,GAAW,EAAC;AAAA,IACd;AAAA,EACF;AACA,EAAA,OAAO;AAAA,IACL,GAAA,EAAK,QAAA,CAAS,QAAA,IAAY,OAAA,CAAQ,IAAI,gBAAA,IAAoB,0BAAA;AAAA,IAC1D,GAAA,EAAK;AAAA,GACP;AACF;AAOO,SAAS,cAAc,IAAA,EAAkC;AAC9D,EAAA,OAAO,cAAA,CAAe,mBAAA,EAAoB,EAAG,IAAI,CAAA;AACnD;AAaA,eAAsB,UAAA,CACpB,MAAA,EACA,IAAA,EACA,IAAA,EAOY;AACZ,EAAA,IAAI,GAAA,GAAM,CAAA,EAAG,MAAA,CAAO,GAAG,GAAG,IAAI,CAAA,CAAA;AAC9B,EAAA,IAAI,MAAM,MAAA,EAAQ;AAChB,IAAA,MAAM,EAAA,GAAK,IAAI,eAAA,CAAgB,IAAA,CAAK,MAAM,CAAA;AAC1C,IAAA,GAAA,IAAO,IAAI,EAAE,CAAA,CAAA;AAAA,EACf;AAEA,EAAA,MAAM,OAAA,GAAkC;AAAA,IACtC,cAAA,EAAgB,kBAAA;AAAA,IAChB,MAAA,EAAQ,kBAAA;AAAA,IACR,GAAI,IAAA,EAAM,OAAA,IAAW;AAAC,GACxB;AACA,EAAA,IAAI,OAAO,GAAA,EAAK;AACd,IAAA,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,MAAA,CAAO,GAAG,CAAA,CAAA;AAAA,EAC9C;AAEA,EAAA,MAAM,SAAA,GAAyB;AAAA,IAC7B,MAAA,EAAQ,MAAM,MAAA,IAAU,KAAA;AAAA,IACxB;AAAA,GACF;AACA,EAAA,IAAI,MAAM,IAAA,EAAM;AACd,IAAA,SAAA,CAAU,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAAA,EAC3C;AAEA,EAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,EAAA,MAAM,OAAA,GAAU,WAAW,MAAM,UAAA,CAAW,OAAM,EAAG,IAAA,EAAM,aAAa,IAAK,CAAA;AAC7E,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK,EAAE,GAAG,SAAA,EAAW,MAAA,EAAQ,UAAA,CAAW,MAAA,EAAQ,CAAA;AACxE,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK,CAAE,KAAA,CAAM,OAAO,EAAE,KAAA,EAAO,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,IAAG,CAAE,CAAA;AAI3E,MAAA,MAAM,CAAA,GAAI,IAAA;AACV,MAAA,MAAM,IAAI,MAAM,CAAA,CAAE,OAAA,IAAW,EAAE,KAAA,IAAS,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,IAC1E;AACA,IAAA,OAAO,IAAI,IAAA,EAAK;AAAA,EAClB,CAAA,SAAE;AACA,IAAA,YAAA,CAAa,OAAO,CAAA;AAAA,EACtB;AACF;AASO,SAAS,oBAAA,GAAgC;AAC9C,EAAA,OAAO,aAAA,CAAc,qBAAqB,CAAA;AAC5C","file":"chunk-Y5B5272E.js","sourcesContent":["/**\n * Keycloak Device Authorization Grant (RFC 8628) for the store CLI: a public\n * device-flow client (`skaile-store-cli`) issues a plain realm JWT the store's\n * `AuthGuard` accepts — a CLI can't use the storefront's confidential browser\n * client. Tokens cache at `~/.skaile/auth.json` (0600, shared with `store/cli`);\n * `getAccessToken` refreshes transparently. All targets are env-overridable.\n *\n * @docLink cli/dev-guide#store-auth\n */\nimport { createHash, randomBytes } from \"node:crypto\";\nimport { chmodSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\n/**\n * A PKCE (RFC 7636) `code_verifier` + its S256 `code_challenge`. Keycloak\n * enforces PKCE on the `skaile-store-cli` device flow (the device-authorization\n * request 400s with \"Missing parameter: code_challenge_method\" otherwise), so\n * every `deviceLogin` mints a fresh pair: the challenge goes on the device-auth\n * request, the verifier on the matching token poll. `base64url` (no padding)\n * per the spec.\n */\nfunction makePkcePair(): { verifier: string; challenge: string } {\n const verifier = randomBytes(32).toString(\"base64url\");\n const challenge = createHash(\"sha256\").update(verifier).digest(\"base64url\");\n return { verifier, challenge };\n}\n\n/** Resolved auth targets — every field has a prod default, all env-overridable. */\nexport interface StoreAuthConfig {\n keycloakUrl: string;\n realm: string;\n clientId: string;\n authFile: string;\n}\n\nfunction trimTrailingSlash(url: string): string {\n return url.replace(/\\/+$/, \"\");\n}\n\n/**\n * Load the auth config. Defaults target the production store\n * (`auth.skaile.ai`, realm `skaile-store`, public client `skaile-store-cli`);\n * override with `SKAILE_KEYCLOAK_URL` / `SKAILE_STORE_REALM` /\n * `SKAILE_STORE_CLI_CLIENT` / `SKAILE_AUTH_FILE` for dev or a preview deploy.\n */\nexport function loadStoreAuthConfig(): StoreAuthConfig {\n const home = process.env.SKAILE_HOME ?? join(homedir(), \".skaile\");\n return {\n keycloakUrl: trimTrailingSlash(process.env.SKAILE_KEYCLOAK_URL ?? \"https://auth.skaile.ai\"),\n realm: process.env.SKAILE_STORE_REALM ?? \"skaile-store\",\n clientId: process.env.SKAILE_STORE_CLI_CLIENT ?? \"skaile-store-cli\",\n authFile: process.env.SKAILE_AUTH_FILE ?? join(home, \"auth.json\"),\n };\n}\n\n/** Keycloak OIDC endpoints derived from the realm base. */\nfunction oidc(config: StoreAuthConfig): { deviceAuth: string; token: string } {\n const base = `${config.keycloakUrl}/realms/${config.realm}/protocol/openid-connect`;\n return { deviceAuth: `${base}/auth/device`, token: `${base}/token` };\n}\n\nexport interface StoredAuth {\n access_token: string;\n refresh_token?: string;\n /** Epoch ms when the access token expires (with a safety margin already applied). */\n expires_at: number;\n}\n\ninterface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n error?: string;\n error_description?: string;\n}\n\ninterface DeviceAuthResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n verification_uri_complete?: string;\n interval?: number;\n expires_in: number;\n}\n\n/** Refresh this many ms before real expiry so an in-flight call never 401s. */\nconst EXPIRY_MARGIN_MS = 30_000;\n\n/** Injectable seams so the poll loop is unit-testable without real time or network. */\nexport interface AuthDeps {\n fetchImpl?: typeof fetch;\n sleep?: (ms: number) => Promise<void>;\n /** Called once with the verification URL + user code (default: write to stderr). */\n onPrompt?: (url: string, userCode: string) => void;\n}\n\nfunction readAuth(config: StoreAuthConfig): StoredAuth | null {\n try {\n const parsed = JSON.parse(readFileSync(config.authFile, \"utf-8\"));\n // Reject a corrupt / hand-edited file rather than treat it as a session.\n if (parsed && typeof parsed.access_token === \"string\") return parsed as StoredAuth;\n return null;\n } catch {\n return null;\n }\n}\n\nfunction writeAuth(config: StoreAuthConfig, auth: StoredAuth): void {\n mkdirSync(dirname(config.authFile), { recursive: true });\n writeFileSync(config.authFile, JSON.stringify(auth, null, 2), { mode: 0o600 });\n chmodSync(config.authFile, 0o600);\n}\n\n/** Remove the cached session (sign out). */\nexport function logout(config: StoreAuthConfig): void {\n try {\n rmSync(config.authFile);\n } catch {\n // already absent — nothing to do\n }\n}\n\n/** True when a cached, well-formed session exists (validity/refresh resolved on use). */\nexport function hasStoredAuth(config: StoreAuthConfig): boolean {\n return readAuth(config) !== null;\n}\n\nfunction tokenToStored(token: TokenResponse): StoredAuth {\n return {\n access_token: token.access_token,\n refresh_token: token.refresh_token,\n expires_at: Date.now() + (token.expires_in ?? 300) * 1000 - EXPIRY_MARGIN_MS,\n };\n}\n\nconst defaultSleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms));\n\nfunction defaultPrompt(url: string, userCode: string): void {\n process.stderr.write(\n `\\nTo sign in, open:\\n\\n ${url}\\n\\nand enter the code: ${userCode}\\n\\nWaiting for approval…\\n`,\n );\n}\n\n/**\n * Run the device flow to completion, persisting tokens on success. Prints the\n * verification URL + user code for the operator to approve in a browser.\n */\nexport async function deviceLogin(\n config: StoreAuthConfig,\n deps: AuthDeps = {},\n): Promise<StoredAuth> {\n const fetchImpl = deps.fetchImpl ?? fetch;\n const sleep = deps.sleep ?? defaultSleep;\n const onPrompt = deps.onPrompt ?? defaultPrompt;\n const endpoints = oidc(config);\n const pkce = makePkcePair();\n\n const deviceRes = await fetchImpl(endpoints.deviceAuth, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n client_id: config.clientId,\n scope: \"openid profile\",\n code_challenge: pkce.challenge,\n code_challenge_method: \"S256\",\n }),\n });\n if (!deviceRes.ok) {\n throw new Error(\n `Device authorization request failed (${deviceRes.status}): ${await deviceRes.text()}`,\n );\n }\n const device = (await deviceRes.json()) as DeviceAuthResponse;\n\n onPrompt(device.verification_uri_complete ?? device.verification_uri, device.user_code);\n\n const intervalMs = (device.interval ?? 5) * 1000;\n const deadline = Date.now() + device.expires_in * 1000;\n let waitMs = intervalMs;\n\n while (Date.now() < deadline) {\n await sleep(waitMs);\n const tokenRes = await fetchImpl(endpoints.token, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n device_code: device.device_code,\n client_id: config.clientId,\n code_verifier: pkce.verifier,\n }),\n });\n const token = (await tokenRes.json()) as TokenResponse;\n if (tokenRes.ok) {\n const stored = tokenToStored(token);\n writeAuth(config, stored);\n return stored;\n }\n // RFC 8628 §3.5 pending / slow-down handling.\n if (token.error === \"authorization_pending\") continue;\n if (token.error === \"slow_down\") {\n waitMs += 5_000;\n continue;\n }\n throw new Error(`Sign-in failed: ${token.error_description ?? token.error ?? \"unknown error\"}`);\n }\n throw new Error(\"Sign-in timed out before approval.\");\n}\n\n/** Exchange a refresh token for a fresh access token; persist on success. */\nasync function refresh(\n config: StoreAuthConfig,\n refreshToken: string,\n fetchImpl: typeof fetch,\n): Promise<StoredAuth> {\n const res = await fetchImpl(oidc(config).token, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n client_id: config.clientId,\n }),\n });\n const token = (await res.json()) as TokenResponse;\n if (!res.ok) {\n throw new Error(\n `Token refresh failed: ${token.error_description ?? token.error ?? res.status}`,\n );\n }\n const stored = tokenToStored(token);\n writeAuth(config, stored);\n return stored;\n}\n\n/**\n * Return a valid access token, refreshing if it is expired (or about to). Throws\n * a clear \"run `skaile store login`\" error when there is no usable session.\n */\nexport async function getAccessToken(\n config: StoreAuthConfig,\n deps: AuthDeps = {},\n): Promise<string> {\n const fetchImpl = deps.fetchImpl ?? fetch;\n const auth = readAuth(config);\n if (!auth) throw new Error(\"Not signed in. Run `skaile store login` first.\");\n if (Date.now() < auth.expires_at) return auth.access_token;\n if (!auth.refresh_token) throw new Error(\"Session expired. Run `skaile store login` again.\");\n try {\n return (await refresh(config, auth.refresh_token, fetchImpl)).access_token;\n } catch {\n throw new Error(\"Session expired and refresh failed. Run `skaile store login` again.\");\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { globalSettingsPath, mapLegacyFields } from \"@skaile/workspaces/core\";\nimport { type AuthDeps, getAccessToken, hasStoredAuth, loadStoreAuthConfig } from \"./store-auth.ts\";\n\n/**\n * Connection configuration for the AI Asset Store API. `jwt` is normally left\n * null here and filled per-call by the caller from {@link getStoreToken} (the\n * device-flow session); it stays on the type for the `{ ...config, jwt }` spread.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport interface StoreConfig {\n url: string;\n jwt: string | null;\n}\n\n/**\n * Read the store API base URL (settings `storeUrl` → `SKAILE_STORE_URL` →\n * default). Auth is not read here — it lives in the device-flow session; see\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function getStoreConfig(): StoreConfig {\n const settingsPath = globalSettingsPath();\n let settings: Record<string, any> = {};\n if (existsSync(settingsPath)) {\n try {\n settings = mapLegacyFields(JSON.parse(readFileSync(settingsPath, \"utf-8\")));\n } catch {\n settings = {};\n }\n }\n return {\n url: settings.storeUrl ?? process.env.SKAILE_STORE_URL ?? \"https://api.skaile.store\",\n jwt: null,\n };\n}\n\n/**\n * Return a valid store access token (Keycloak device-flow session, refreshed if\n * needed). Throws a \"run `skaile store login`\" error when there is no session.\n * This is the auth source for every `/api/v1/*` publisher call.\n */\nexport function getStoreToken(deps?: AuthDeps): Promise<string> {\n return getAccessToken(loadStoreAuthConfig(), deps);\n}\n\n/**\n * Make an authenticated HTTP request to the store REST API.\n *\n * @param config - Store connection config (URL + auth token).\n * @param path - API path (e.g. `/api/assets`).\n * @param opts - Optional method, body, query params, extra headers, and\n * `timeoutMs` (default 1500). Publisher calls pass a longer timeout because\n * they trigger server-side clone/sync work.\n * @returns Parsed JSON response body.\n * @docLink cli/dev-guide#store-client\n */\nexport async function storeFetch<T = any>(\n config: StoreConfig,\n path: string,\n opts?: {\n method?: string;\n body?: unknown;\n params?: Record<string, string>;\n headers?: Record<string, string>;\n timeoutMs?: number;\n },\n): Promise<T> {\n let url = `${config.url}${path}`;\n if (opts?.params) {\n const sp = new URLSearchParams(opts.params);\n url += `?${sp}`;\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...(opts?.headers ?? {}),\n };\n if (config.jwt) {\n headers.Authorization = `Bearer ${config.jwt}`;\n }\n\n const fetchOpts: RequestInit = {\n method: opts?.method ?? \"GET\",\n headers,\n };\n if (opts?.body) {\n fetchOpts.body = JSON.stringify(opts.body);\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), opts?.timeoutMs ?? 1_500);\n try {\n const res = await fetch(url, { ...fetchOpts, signal: controller.signal });\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));\n // Prefer the store's human-readable `message` (e.g. \"Namespace '@x' is\n // reserved … Sign in with GitHub to claim it\") over the bare `error` code\n // (`UNPROCESSABLE_CONTENT`) — the message is the actionable part.\n const b = body as { message?: string; error?: string };\n throw new Error(b.message ?? b.error ?? `Store API error: ${res.status}`);\n }\n return res.json() as Promise<T>;\n } finally {\n clearTimeout(timeout);\n }\n}\n\n/**\n * Return `true` when a store session exists (a Keycloak device-flow token cached\n * at `~/.skaile/auth.json`). Validity/refresh is resolved on use via\n * {@link getStoreToken}.\n *\n * @docLink cli/dev-guide#store-client\n */\nexport function isStoreAuthenticated(): boolean {\n return hasStoredAuth(loadStoreAuthConfig());\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../cli/src/commands/library-publish.ts"],"names":[],"mappings":"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","file":"library-publish-NQQFPOUY.js","sourcesContent":["/**\n * `skaile library publish / register / yank` — the first-party publish flow.\n * A git-backed library you own carries an in-repo `skaile.manifest.yaml`; this\n * commits + pushes the library repo (publish), or takes the current remote HEAD\n * as-is (register), then registers + syncs it as a store source and publishes\n * the manifest's assets under the manifest's own `publisher` (no namespace\n * remap — first-party authors intend their declared namespace).\n *\n * - `publish` = commit (if dirty) + push + register + sync + publish.\n * - `register` = same, but skip the commit/push (bytes already on GitHub).\n * - `yank` = unpublish the library's published assets (all, or one).\n *\n * The store REST surface is reached through the injectable {@link PublisherClient}\n * (default HTTP); git side-effects go through an injectable `spawn`. Both seams\n * keep the flow unit/integration-testable without a live store or a real remote.\n *\n * @docLink cli/commands/library\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { decodeSkaileManifest, type SkPublishManifest } from \"@skaile/workspaces/core\";\nimport type { GitBackendConfig, Library } from \"@skaile/workspaces/library\";\nimport { logErr, logInfo, logOk, S } from \"../helpers.ts\";\nimport { openLibraryManager } from \"../open-library.ts\";\nimport { isStoreAuthenticated } from \"../store-client.ts\";\nimport { makeHttpPublisherClient, type PublisherClient } from \"../store-publisher.ts\";\nimport { bareName, publishToStore, refFor } from \"./publish-core.ts\";\n\n/** Injectable spawn contract — the subset of `spawnSync` these helpers use. */\ntype SpawnLike = typeof spawnSync;\n\n/** The fixed filename a library carries at its root for publication. */\nconst MANIFEST_FILENAME = \"skaile.manifest.yaml\";\n\n/** The remote url of a git-backed library, or `undefined` for a local one. */\nfunction remoteUrlOf(lib: Library): string | undefined {\n if (lib.backend !== \"git\") return undefined;\n return (lib.backendConfig as GitBackendConfig).url;\n}\n\n/** The publish branch of a git-backed library (defaults to `main`). */\nfunction branchOf(lib: Library): string {\n if (lib.backend !== \"git\") return \"main\";\n return (lib.backendConfig as GitBackendConfig).branch ?? \"main\";\n}\n\n/**\n * Read + decode the in-repo `skaile.manifest.yaml`. Prints each error\n * diagnostic and exits (1) — mirroring the sidecar flow's validation gate.\n */\nfunction loadManifest(libPath: string): SkPublishManifest {\n let text: string;\n try {\n text = readFileSync(join(libPath, MANIFEST_FILENAME), \"utf-8\");\n } catch {\n logErr(\n `No ${S.dim(MANIFEST_FILENAME)} in the library — author it (see \\`skaile library create\\`) ` +\n \"and run `skaile validate` before publishing.\",\n );\n process.exit(1);\n }\n const { manifest, diagnostics } = decodeSkaileManifest(text);\n const errors = diagnostics.filter((d) => d.severity === \"error\");\n if (errors.length > 0) {\n for (const d of errors) logErr(`${d.code}: ${d.message}`);\n logErr(\"The manifest has errors — fix them with `skaile validate` before publishing.\");\n process.exit(1);\n }\n return manifest;\n}\n\n/** Run a git command in `cwd` via the injected spawn; returns the result. */\nfunction runGit(spawn: SpawnLike, cwd: string, args: string[]) {\n return spawn(\"git\", [\"-C\", cwd, ...args], { encoding: \"utf-8\" });\n}\n\n/**\n * Ensure `libPath` is a git repo whose `origin` points at `remoteUrl`, then\n * commit any changes and push to `branch`. Idempotent re-publish: an unchanged\n * tree makes `git commit` fail with \"nothing to commit\" — swallowed. Push (or\n * any other git) failures surface as thrown Errors carrying git's stderr.\n */\nfunction commitAndPush(opts: {\n libPath: string;\n remoteUrl: string;\n branch: string;\n spawn: SpawnLike;\n}): void {\n const { libPath, remoteUrl, branch, spawn } = opts;\n\n const gitDir = runGit(spawn, libPath, [\"rev-parse\", \"--git-dir\"]);\n if (gitDir.status !== 0) {\n const init = runGit(spawn, libPath, [\"init\"]);\n if (init.status !== 0) {\n throw new Error(\n `git init failed: ${(init.stderr ?? \"\").toString().trim() || `exit ${init.status}`}`,\n );\n }\n }\n\n // Point origin at the resolved remote (add if absent, else set-url).\n const getUrl = runGit(spawn, libPath, [\"remote\", \"get-url\", \"origin\"]);\n const originArgs =\n getUrl.status === 0\n ? [\"remote\", \"set-url\", \"origin\", remoteUrl]\n : [\"remote\", \"add\", \"origin\", remoteUrl];\n const setOrigin = runGit(spawn, libPath, originArgs);\n if (setOrigin.status !== 0) {\n throw new Error(\n `git remote failed: ${(setOrigin.stderr ?? \"\").toString().trim() || `exit ${setOrigin.status}`}`,\n );\n }\n\n const add = runGit(spawn, libPath, [\"add\", \"-A\"]);\n if (add.status !== 0) {\n throw new Error(\n `git add failed: ${(add.stderr ?? \"\").toString().trim() || `exit ${add.status}`}`,\n );\n }\n\n // Fixed bot identity via -c so the commit succeeds regardless of the author's\n // git config (the publish commit is a machine action).\n const commit = spawn(\n \"git\",\n [\n \"-C\",\n libPath,\n \"-c\",\n \"user.email=publish@skaile.store\",\n \"-c\",\n \"user.name=skaile\",\n \"commit\",\n \"-m\",\n \"chore: publish\",\n ],\n { encoding: \"utf-8\" },\n );\n if (commit.status !== 0) {\n const out = `${commit.stdout ?? \"\"}${commit.stderr ?? \"\"}`;\n if (!/nothing to commit/i.test(out)) {\n throw new Error(`git commit failed: ${out.trim() || `exit ${commit.status}`}`);\n }\n }\n\n const push = runGit(spawn, libPath, [\"push\", \"origin\", `HEAD:${branch}`]);\n if (push.status !== 0) {\n throw new Error(\n `git push failed: ${(push.stderr ?? \"\").toString().trim() || `exit ${push.status}`}`,\n );\n }\n}\n\n/**\n * Provision a public GitHub repo `github.com/<you>/<name>` via `gh` and return\n * its https url. Parses the url `gh` prints on success. Throws on failure.\n */\nfunction createRepoViaGh(name: string, spawn: SpawnLike): string {\n const res = spawn(\"gh\", [\"repo\", \"create\", name, \"--public\"], { encoding: \"utf-8\" });\n if (res.status !== 0) {\n const stderr = (res.stderr ?? \"\").toString().trim();\n throw new Error(`gh repo create ${name} failed: ${stderr || `exit ${res.status}`}`);\n }\n // `gh repo create` prints the repo url (e.g. `https://github.com/<owner>/<name>`);\n // scan combined output for the first github.com url so we capture whatever\n // owner gh resolved (the authed user).\n const out = `${res.stdout ?? \"\"}\\n${res.stderr ?? \"\"}`;\n const match = out.match(/https:\\/\\/github\\.com\\/[^\\s]+/);\n if (!match) {\n throw new Error(`gh repo create ${name} succeeded but printed no repo url:\\n${out.trim()}`);\n }\n return match[0].replace(/\\.git$/, \"\").trim();\n}\n\n/** Shared publish body for `publish` (pushes) and `register` (skips the push). */\nasync function publishLibrary(\n name: string,\n opts: {\n asset?: string;\n createRepo?: boolean;\n ref?: string;\n dryRun?: boolean;\n skipPush: boolean;\n },\n client?: PublisherClient,\n spawn: SpawnLike = spawnSync,\n): Promise<void> {\n const injected = client !== undefined;\n const { manager, close } = await openLibraryManager();\n try {\n const lib = await manager.requireLibrary(name);\n const manifest = loadManifest(lib.path);\n\n // Resolve the remote: git-backed → its url; local + --create-repo → provision\n // and link; else stop with a hint.\n let remoteUrl = remoteUrlOf(lib);\n let wouldCreateRepo = false;\n if (!remoteUrl) {\n if (opts.createRepo) {\n if (opts.dryRun) {\n // A dry-run must not provision anything — defer the real\n // `gh repo create` to the live run and just show the would-be remote.\n wouldCreateRepo = true;\n remoteUrl = `https://github.com/<your-account>/${lib.name}`;\n } else {\n remoteUrl = createRepoViaGh(lib.name, spawn);\n await manager.updateLibrary(name, {\n backend: \"git\",\n backendConfig: { url: remoteUrl, branch: \"main\", authHint: \"ssh\" },\n });\n logOk(`Created + linked ${S.dim(remoteUrl)}.`);\n }\n } else {\n logErr(\n `Library \"${name}\" has no remote — run ${S.cmd(`skaile library link ${name} <url>`)} ` +\n \"first, or pass `--create-repo` to provision a public repo.\",\n );\n process.exit(1);\n }\n }\n\n // The manifest's own publisher is the namespace (first-party — no remap).\n const namespace = manifest.publisher ?? \"<manifest publisher>\";\n const targetName = opts.asset ? bareName(opts.asset) : undefined;\n const wouldBeRefs = (manifest.assets ?? [])\n .filter((a) => !targetName || a.name === targetName)\n .map((a) => refFor(a.kind, namespace, a.name, a.version ?? manifest.version));\n\n const sourceRef = opts.ref ?? branchOf(lib);\n\n if (opts.dryRun) {\n logInfo(`Publish plan for ${S.bold(name)}:`);\n logInfo(\n ` remote: ${remoteUrl}${wouldCreateRepo ? \" (would be created via `gh repo create --public`)\" : \"\"}`,\n );\n logInfo(` publisher: ${namespace}`);\n logInfo(` source ref: ${sourceRef}`);\n logInfo(` would publish ${wouldBeRefs.length} asset(s):`);\n for (const r of wouldBeRefs) logInfo(` ${r}`);\n return;\n }\n\n // A real publish makes store calls, so it needs a token (injected fakes bypass).\n if (!injected && !isStoreAuthenticated()) {\n logErr(\"Not signed in — run `skaile store login` first.\");\n process.exit(1);\n }\n\n // publish commits + pushes the library repo; register takes the remote HEAD as-is.\n if (!opts.skipPush) {\n // `git add -A` stages every non-ignored file → a PUBLIC push. Surface it so\n // an unexpected file in the working tree is not silently published.\n logInfo(\n `Committing the library and pushing to the PUBLIC remote ${S.dim(remoteUrl)} ` +\n \"(.gitignore honored; anything else in the working tree becomes public).\",\n );\n commitAndPush({ libPath: lib.path, remoteUrl, branch: branchOf(lib), spawn });\n logOk(`Pushed ${S.dim(name)} to ${S.dim(remoteUrl)}.`);\n }\n\n const pub = client ?? makeHttpPublisherClient();\n const { published } = await publishToStore({\n sourceUrl: remoteUrl,\n ref: sourceRef,\n manifest,\n assetName: targetName,\n client: pub,\n });\n\n if (published.length > 0) {\n logInfo(`Consumers can now \\`skaile add ${published[0]}\\`.`);\n }\n } finally {\n close();\n }\n}\n\n/**\n * `skaile library publish <lib>` — commit + push the library repo, register +\n * sync it as a store source, and publish its manifest's assets under the\n * manifest publisher. See the module header for the full flow.\n */\nexport async function runLibraryPublish(\n name: string,\n opts: { asset?: string; createRepo?: boolean; ref?: string; dryRun?: boolean },\n client?: PublisherClient,\n spawn: SpawnLike = spawnSync,\n): Promise<void> {\n await publishLibrary(name, { ...opts, skipPush: false }, client, spawn);\n}\n\n/**\n * `skaile library register <lib>` — same as publish but skips the commit/push\n * (the bytes are already on GitHub at the current remote HEAD). Still requires a\n * git-backed remote.\n */\nexport async function runLibraryRegister(\n name: string,\n opts: { asset?: string; ref?: string; dryRun?: boolean },\n client?: PublisherClient,\n spawn: SpawnLike = spawnSync,\n): Promise<void> {\n await publishLibrary(name, { ...opts, skipPush: true }, client, spawn);\n}\n\n/**\n * `skaile library yank <lib>` — unpublish the library's published assets from\n * the store (all, or the single asset matching `opts.asset`'s name).\n * Auth-gated like publish.\n */\nexport async function runLibraryYank(\n name: string,\n opts: { asset?: string },\n client?: PublisherClient,\n): Promise<void> {\n const injected = client !== undefined;\n const { manager, close } = await openLibraryManager();\n try {\n const lib = await manager.requireLibrary(name);\n const remoteUrl = remoteUrlOf(lib);\n if (!remoteUrl) {\n logErr(`Library \"${name}\" has no remote — nothing published to yank.`);\n process.exit(1);\n }\n\n if (!injected && !isStoreAuthenticated()) {\n logErr(\"Not signed in — run `skaile store login` first.\");\n process.exit(1);\n }\n\n const pub = client ?? makeHttpPublisherClient();\n const rows = await pub.sourcesList();\n const source = rows.find((r) => r.url === remoteUrl);\n if (!source) {\n logErr(`Library \"${name}\" is not registered in the store — nothing to yank.`);\n process.exit(1);\n }\n\n const targetName = opts.asset ? bareName(opts.asset) : undefined;\n const candidates = (await pub.sourceCandidates(source.id)).filter(\n (c) => c.published && (!targetName || c.name === targetName),\n );\n if (candidates.length === 0) {\n logInfo(\"No published assets matched — nothing to yank.\");\n return;\n }\n\n const yanked: string[] = [];\n for (const c of candidates) {\n try {\n await pub.assetUnpublish(c.id);\n yanked.push(`${c.kind}:${c.name}`);\n } catch (err) {\n logErr(\n `Failed to yank ${c.kind}:${c.name}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n logOk(`Yanked ${yanked.length} asset(s):`);\n for (const r of yanked) logInfo(` ${r}`);\n } finally {\n close();\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../cli/src/commands/source-manifest-publish.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,IAAM,yBAAA,GAA4B,sBAAA;AAW3B,SAAS,0BAAA,CACd,UACA,SAAA,EACmB;AACnB,EAAA,MAAM,UAAU,QAAA,CAAS,MAAA,IAAU,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,KAAM;AAChD,IAAA,MAAM,EAAE,SAAA,EAAW,KAAA,EAAO,GAAG,MAAK,GAAI,CAAA;AACtC,IAAA,OAAO,IAAA;AAAA,EACT,CAAC,CAAA;AACD,EAAA,OAAO,EAAE,GAAG,QAAA,EAAU,SAAA,EAAW,WAAW,MAAA,EAAO;AACrD;AAWA,SAAS,YAAA,GAAuB;AAC9B,EAAA,MAAM,OAAO,OAAA,CAAQ,GAAA,CAAI,eAAe,IAAA,CAAK,OAAA,IAAW,SAAS,CAAA;AACjE,EAAA,OAAO,IAAA,CAAK,MAAM,eAAe,CAAA;AACnC;AAEA,SAAS,YAAA,GAAoC;AAC3C,EAAA,MAAM,OAAO,YAAA,EAAa;AAC1B,EAAA,IAAI,CAAC,UAAA,CAAW,IAAI,CAAA,SAAU,EAAC;AAC/B,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,YAAA,CAAa,IAAA,EAAM,OAAO,CAAC,CAAA;AAAA,EAC/C,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAC;AAAA,EACV;AACF;AAMO,SAAS,eAAe,IAAA,EAAkC;AAC/D,EAAA,MAAM,WAAW,YAAA,EAAa;AAC9B,EAAA,OAAO,QAAA,CAAS,YAAA,GAAe,IAAI,CAAA,EAAG,IAAA;AACxC;AAOO,SAAS,eAAA,CAAgB,MAAc,IAAA,EAAoB;AAChE,EAAA,MAAM,OAAO,YAAA,EAAa;AAC1B,EAAA,SAAA,CAAU,QAAQ,IAAI,CAAA,EAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAC5C,EAAA,MAAM,WAAW,YAAA,EAAa;AAC9B,EAAA,MAAM,eAAe,EAAE,GAAI,QAAA,CAAS,YAAA,IAAgB,EAAC,EAAG;AACxD,EAAA,YAAA,CAAa,IAAI,IAAI,EAAE,GAAI,aAAa,IAAI,CAAA,IAAK,EAAC,EAAI,IAAA,EAAK;AAC3D,EAAA,QAAA,CAAS,YAAA,GAAe,YAAA;AACxB,EAAA,aAAA,CAAc,MAAM,IAAA,CAAK,SAAA,CAAU,UAAU,IAAA,EAAM,CAAC,GAAG,OAAO,CAAA;AAChE;AAQA,SAAS,GAAA,CAAI,KAAA,EAAkB,GAAA,EAAa,IAAA,EAAwB;AAClE,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,KAAA,EAAO,CAAC,IAAA,EAAM,GAAA,EAAK,GAAG,IAAI,CAAA,EAAG,EAAE,QAAA,EAAU,OAAA,EAAS,CAAA;AACpE,EAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACpB,IAAA,MAAM,UAAU,GAAA,CAAI,MAAA,IAAU,EAAA,EAAI,QAAA,GAAW,IAAA,EAAK;AAClD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,IAAA,EAAO,IAAA,CAAK,IAAA,CAAK,GAAG,CAAC,CAAA,SAAA,EAAY,MAAA,IAAU,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,EAAE,CAAA,CAAE,CAAA;AAAA,EACnF;AACA,EAAA,OAAA,CAAQ,GAAA,CAAI,MAAA,IAAU,EAAA,EAAI,QAAA,GAAW,IAAA,EAAK;AAC5C;AAWO,SAAS,oBAAoB,IAAA,EAIV;AACxB,EAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,SAAA;AAG5B,EAAA,MAAM,WAAW,CAAA,EAAG,eAAA,CAAgB,eAAe,IAAA,CAAK,cAAc,CAAC,CAAC,CAAA,aAAA,CAAA;AACxE,EAAA,MAAA,CAAO,UAAU,EAAE,SAAA,EAAW,IAAA,EAAM,KAAA,EAAO,MAAM,CAAA;AACjD,EAAA,SAAA,CAAU,QAAQ,QAAQ,CAAA,EAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAIhD,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,KAAA,EAAO,CAAC,OAAA,EAAS,WAAW,GAAA,EAAK,IAAA,CAAK,cAAA,EAAgB,QAAQ,CAAA,EAAG;AAAA,MACtF,QAAA,EAAU;AAAA,KACX,CAAA;AACD,IAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,MAAA,MAAM,UAAU,QAAA,CAAS,MAAA,IAAU,EAAA,EAAI,QAAA,GAAW,IAAA,EAAK;AACvD,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,UAAA,EAAa,KAAK,cAAc,CAAA,SAAA,EAAY,UAAU,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,OACjF;AAAA,IACF;AAEA,IAAA,aAAA,CAAc,KAAK,QAAA,EAAU,yBAAyB,CAAA,EAAG,IAAA,CAAK,cAAc,OAAO,CAAA;AACnF,IAAA,GAAA,CAAI,KAAA,EAAO,QAAA,EAAU,CAAC,KAAA,EAAO,yBAAyB,CAAC,CAAA;AAIvD,IAAA,MAAM,SAAA,GAAY,KAAA;AAAA,MAChB,KAAA;AAAA,MACA;AAAA,QACE,IAAA;AAAA,QACA,QAAA;AAAA,QACA,IAAA;AAAA,QACA,iCAAA;AAAA,QACA,IAAA;AAAA,QACA,kBAAA;AAAA,QACA,QAAA;AAAA,QACA,IAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,EAAE,UAAU,OAAA;AAAQ,KACtB;AACA,IAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,MAAA,MAAM,GAAA,GAAM,GAAG,SAAA,CAAU,MAAA,IAAU,EAAE,CAAA,EAAG,SAAA,CAAU,UAAU,EAAE,CAAA,CAAA;AAE9D,MAAA,IAAI,CAAC,oBAAA,CAAqB,IAAA,CAAK,GAAG,CAAA,EAAG;AACnC,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,GAAA,CAAI,IAAA,MAAU,CAAA,KAAA,EAAQ,SAAA,CAAU,MAAM,CAAA,CAAE,CAAA,CAAE,CAAA;AAAA,MAClF;AAAA,IACF,CAAA,MAAO;AAGL,MAAA,GAAA,CAAI,OAAO,QAAA,EAAU,CAAC,MAAA,EAAQ,QAAA,EAAU,MAAM,CAAC,CAAA;AAAA,IACjD;AAEA,IAAA,OAAO,EAAE,WAAW,GAAA,CAAI,KAAA,EAAO,UAAU,CAAC,WAAA,EAAa,MAAM,CAAC,CAAA,EAAE;AAAA,EAClE,CAAA,SAAE;AACA,IAAA,MAAA,CAAO,UAAU,EAAE,SAAA,EAAW,IAAA,EAAM,KAAA,EAAO,MAAM,CAAA;AAAA,EACnD;AACF;AAWA,eAAsB,UAAA,CACpB,GAAA,EACA,IAAA,EAOA,MAAA,EACA,QAAmB,SAAA,EACJ;AACf,EAAA,MAAM,WAAW,MAAA,KAAW,MAAA;AAC5B,EAAA,MAAM,GAAA,GAAM,UAAU,uBAAA,EAAwB;AAE9C,EAAA,MAAM,EAAE,KAAK,IAAA,EAAM,YAAA,KAAiB,gBAAA,CAAiB,GAAA,EAAK,KAAK,UAAU,CAAA;AAEzE,EAAA,IAAI,CAAC,UAAA,CAAW,YAAY,CAAA,EAAG;AAC7B,IAAA,MAAA;AAAA,MACE,4BAA4B,IAAI,CAAA,KAAA,EAAQ,CAAA,CAAE,GAAA,CAAI,YAAY,CAAC,CAAA,kDAAA;AAAA,KAE7D;AACA,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAEA,EAAA,MAAM,EAAE,UAAU,WAAA,EAAY,GAAI,qBAAqB,YAAA,CAAa,YAAA,EAAc,OAAO,CAAC,CAAA;AAC1F,EAAA,IAAI,YAAY,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,QAAA,KAAa,OAAO,CAAA,EAAG;AACnD,IAAA,KAAA,MAAW,CAAA,IAAK,YAAY,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,QAAA,KAAa,OAAO,CAAA,EAAG;AACjE,MAAA,MAAA,CAAO,GAAG,CAAA,CAAE,IAAI,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA;AAAA,IAClC;AACA,IAAA,MAAA;AAAA,MACE;AAAA,KAEF;AACA,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAIA,EAAA,MAAM,MAAA,GAAS,YAAY,oBAAA,EAAqB;AAChD,EAAA,IAAI,CAAC,IAAA,CAAK,MAAA,IAAU,CAAC,MAAA,EAAQ;AAC3B,IAAA,MAAA,CAAO,sDAAiD,CAAA;AACxD,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAIA,EAAA,IAAI,SAAA;AACJ,EAAA,IAAI,IAAA,CAAK,EAAA,EAAI,SAAA,GAAY,IAAA,CAAK,EAAA;AAAA,OAAA,IACrB,MAAA,EAAQ,SAAA,GAAA,CAAa,MAAM,GAAA,CAAI,IAAG,EAAG,QAAA;AAAA,OACzC,SAAA,GAAY,uBAAA;AAEjB,EAAA,MAAM,UAAA,GAAa,0BAAA,CAA2B,QAAA,EAAU,SAAS,CAAA;AACjE,EAAA,MAAM,aAAA,GAAgB,qBAAqB,UAAU,CAAA;AAErD,EAAA,MAAM,WAAA,GAAA,CAAe,UAAA,CAAW,MAAA,IAAU,EAAC,EAAG,GAAA;AAAA,IAAI,CAAC,CAAA,KACjD,MAAA,CAAO,CAAA,CAAE,IAAA,EAAM,SAAA,EAAW,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,OAAA,IAAW,UAAA,CAAW,OAAO;AAAA,GACnE;AAEA,EAAA,IAAI,KAAK,MAAA,EAAQ;AACf,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,WAAA,IAAe,cAAA,CAAe,IAAI,CAAA,IAAK,mCAAA;AAC5D,IAAA,OAAA,CAAQ,CAAA,iBAAA,EAAoB,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAG,CAAA;AAC3C,IAAA,OAAA,CAAQ,CAAA,gBAAA,EAAmB,SAAS,CAAA,CAAE,CAAA;AACtC,IAAA,OAAA,CAAQ,CAAA,gBAAA,EAAmB,OAAO,CAAA,CAAE,CAAA;AACpC,IAAA,OAAA,CAAQ,CAAA,gBAAA,EAAmB,IAAA,CAAK,GAAA,IAAO,MAAM,CAAA,CAAE,CAAA;AAC/C,IAAA,OAAA,CAAQ,CAAA,gBAAA,EAAmB,WAAA,CAAY,MAAM,CAAA,UAAA,CAAY,CAAA;AACzD,IAAA,KAAA,MAAW,CAAA,IAAK,WAAA,EAAa,OAAA,CAAQ,CAAA,IAAA,EAAO,CAAC,CAAA,CAAE,CAAA;AAC/C,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,WAAA,IAAe,cAAA,CAAe,IAAI,CAAA;AAC9D,EAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,IAAA,MAAA;AAAA,MACE,CAAA,kDAAA,EACK,CAAA,CAAE,GAAA,CAAI,gDAAgD,CAAC,CAAA,2HAAA;AAAA,KAG9D;AACA,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACA,EAAA,IAAI,IAAA,CAAK,WAAA,EAAa,eAAA,CAAgB,IAAA,EAAM,cAAc,CAAA;AAE1D,EAAA,MAAM,EAAE,WAAU,GAAI,mBAAA,CAAoB,EAAE,cAAA,EAAgB,YAAA,EAAc,aAAA,EAAe,KAAA,EAAO,CAAA;AAChG,EAAA,KAAA,CAAM,CAAA,2BAAA,EAA8B,CAAA,CAAE,GAAA,CAAI,cAAc,CAAC,CAAA,GAAA,EAAM,SAAA,CAAU,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA,CAAA,CAAG,CAAA;AAGxF,EAAA,MAAM,SAAA,GAAY,KAAK,GAAA,IAAO,MAAA;AAE9B,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,MAAM,cAAA,CAAe;AAAA,IACzC,SAAA,EAAW,GAAA;AAAA,IACX,GAAA,EAAK,SAAA;AAAA,IACL,OAAA,EAAS,EAAE,GAAA,EAAK,cAAA,EAAgB,KAAK,SAAA,EAAU;AAAA,IAC/C,QAAA,EAAU,UAAA;AAAA,IACV,MAAA,EAAQ;AAAA,GACT,CAAA;AAED,EAAA,IAAI,SAAA,CAAU,SAAS,CAAA,EAAG;AACxB,IAAA,OAAA,CAAQ,CAAA,iDAAA,EAAoD,SAAA,CAAU,CAAC,CAAC,CAAA,GAAA,CAAK,CAAA;AAAA,EAC/E;AACF;AAMA,eAAsB,OAAA,CACpB,GAAA,EACA,IAAA,EACA,MAAA,EACe;AACf,EAAA,MAAM,WAAW,MAAA,KAAW,MAAA;AAC5B,EAAA,MAAM,GAAA,GAAM,UAAU,uBAAA,EAAwB;AAE9C,EAAA,MAAM,EAAE,GAAA,EAAK,IAAA,KAAS,gBAAA,CAAiB,GAAA,EAAK,KAAK,UAAU,CAAA;AAE3D,EAAA,IAAI,CAAC,QAAA,IAAY,CAAC,oBAAA,EAAqB,EAAG;AACxC,IAAA,MAAA,CAAO,sDAAiD,CAAA;AACxD,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAEA,EAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,WAAA,EAAY;AACnC,EAAA,MAAM,SAAS,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,QAAQ,GAAG,CAAA;AAC7C,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAA,CAAO,CAAA,QAAA,EAAW,IAAI,CAAA,wDAAA,CAAqD,CAAA;AAC3E,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAGA,EAAA,MAAM,aAAa,IAAA,CAAK,KAAA,GAAQ,QAAA,CAAS,IAAA,CAAK,KAAK,CAAA,GAAI,MAAA;AACvD,EAAA,MAAM,cAAc,MAAM,GAAA,CAAI,gBAAA,CAAiB,MAAA,CAAO,EAAE,CAAA,EAAG,MAAA;AAAA,IACzD,CAAC,CAAA,KAAM,CAAA,CAAE,cAAc,CAAC,UAAA,IAAc,EAAE,IAAA,KAAS,UAAA;AAAA,GACnD;AACA,EAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,IAAA,OAAA,CAAQ,qDAAgD,CAAA;AACxD,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC1B,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,CAAI,cAAA,CAAe,CAAA,CAAE,EAAE,CAAA;AAC7B,MAAA,MAAA,CAAO,KAAK,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,IAAI,CAAA,CAAE,CAAA;AAAA,IACnC,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA;AAAA,QACE,CAAA,eAAA,EAAkB,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,IAAI,CAAA,EAAA,EAAK,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,OACzF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,KAAA,CAAM,CAAA,OAAA,EAAU,MAAA,CAAO,MAAM,CAAA,UAAA,CAAY,CAAA;AACzC,EAAA,KAAA,MAAW,CAAA,IAAK,MAAA,EAAQ,OAAA,CAAQ,CAAA,EAAA,EAAK,CAAC,CAAA,CAAE,CAAA;AAC1C","file":"source-manifest-publish-HJ5G4CTH.js","sourcesContent":["/**\n * `skaile source manifest publish` / `yank` — the curator-publish flow. Takes a\n * locally-curated sidecar manifest (over a foreign public GitHub repo) and:\n *\n * 1. Pushes the curated `skaile.manifest.yaml` to the curator's OWN public\n * \"sidecar\" repo (bytes stay in the foreign source; the sidecar holds only\n * the manifest pointing at it).\n * 2. Registers the foreign source + the sidecar (url + pinned commit) with the\n * store, syncs it, and publishes each curated asset.\n *\n * `yank` is the inverse: unpublish each currently-published asset of the source.\n *\n * The store REST surface is reached through the injectable {@link PublisherClient}\n * (default HTTP client); git side-effects go through an injectable `spawn`. Both\n * seams keep the pure helpers + orchestration unit/integration-testable without a\n * live store or a real remote.\n *\n * @docLink cli/commands/source#manifest-publish\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport {\n decodeSkaileManifest,\n encodeSkaileManifest,\n type SkPublishManifest,\n sourceCacheKey,\n} from \"@skaile/workspaces/core\";\nimport { logErr, logInfo, logOk, logWarn, S } from \"../helpers.ts\";\nimport { makeHttpPublisherClient, type PublisherClient } from \"../store-publisher.ts\";\nimport { isStoreAuthenticated } from \"../store-client.ts\";\nimport { bareName, publishToStore, refFor } from \"./publish-core.ts\";\nimport { sourceClonePath } from \"./source.ts\";\nimport { resolveSourceArg } from \"./source-manifest.ts\";\n\n/** The fixed filename a sidecar repo carries at its root. */\nconst SIDECAR_MANIFEST_FILENAME = \"skaile.manifest.yaml\";\n\n/** Injectable spawn contract — the subset of `spawnSync` these helpers use. */\ntype SpawnLike = typeof spawnSync;\n\n/**\n * Return a copy of `manifest` normalized for publication under `namespace`:\n * the top-level `publisher` is set to `namespace` and every per-asset\n * `publisher` override is removed so all assets inherit the top-level one.\n * Pure — the input is not mutated.\n */\nexport function normalizePublishedManifest(\n manifest: SkPublishManifest,\n namespace: string,\n): SkPublishManifest {\n const assets = (manifest.assets ?? []).map((a) => {\n const { publisher: _drop, ...rest } = a;\n return rest;\n });\n return { ...manifest, publisher: namespace, assets };\n}\n\n// ── Sidecar-repo association (~/.skaile/settings.json) ────────────────────────\n\n/**\n * Path to the user settings file — the same `~/.skaile/settings.json` the store\n * client reads tokens from. Resolves the `.skaile` root exactly as `getStoreRoot`\n * does (`SKAILE_HOME` when set — it IS the `.skaile` dir — else `~/.skaile`), so\n * the sidecar association lives beside the store manifests under one convention\n * and tests isolate through the same `SKAILE_HOME` seam.\n */\nfunction settingsFile(): string {\n const root = process.env.SKAILE_HOME ?? join(homedir(), \".skaile\");\n return join(root, \"settings.json\");\n}\n\nfunction readSettings(): Record<string, any> {\n const file = settingsFile();\n if (!existsSync(file)) return {};\n try {\n return JSON.parse(readFileSync(file, \"utf-8\"));\n } catch {\n return {};\n }\n}\n\n/**\n * The sidecar repo URL previously associated with a source `slug`, if any.\n * Reads `settings.sidecarRepos?.[slug]?.repo`.\n */\nexport function getSidecarRepo(slug: string): string | undefined {\n const settings = readSettings();\n return settings.sidecarRepos?.[slug]?.repo;\n}\n\n/**\n * Persist the sidecar repo URL for a source `slug`, preserving every other\n * settings key. Stored as an object (`{ repo }`) so a `path` (or other fields)\n * can be added later without a schema migration.\n */\nexport function saveSidecarRepo(slug: string, repo: string): void {\n const file = settingsFile();\n mkdirSync(dirname(file), { recursive: true });\n const settings = readSettings();\n const sidecarRepos = { ...(settings.sidecarRepos ?? {}) };\n sidecarRepos[slug] = { ...(sidecarRepos[slug] ?? {}), repo };\n settings.sidecarRepos = sidecarRepos;\n writeFileSync(file, JSON.stringify(settings, null, 2), \"utf-8\");\n}\n\n// ── Sidecar push ──────────────────────────────────────────────────────────────\n\n/**\n * Run a git command in `cwd` via the injected spawn, throwing with the captured\n * stderr on failure. Returns trimmed stdout.\n */\nfunction git(spawn: SpawnLike, cwd: string, args: string[]): string {\n const res = spawn(\"git\", [\"-C\", cwd, ...args], { encoding: \"utf-8\" });\n if (res.status !== 0) {\n const stderr = (res.stderr ?? \"\").toString().trim();\n throw new Error(`git ${args.join(\" \")} failed: ${stderr || `exit ${res.status}`}`);\n }\n return (res.stdout ?? \"\").toString().trim();\n}\n\n/**\n * Clone the curator's sidecar repo, write the curated manifest at its root, and\n * commit + push. Returns the pushed commit sha (used to pin the store source).\n *\n * Idempotent re-publish: when the manifest is unchanged `git commit` fails with\n * \"nothing to commit\" — we swallow that and return the current HEAD so a no-op\n * re-run still yields a valid pin. Any push/auth failure surfaces as a thrown\n * Error carrying git's stderr.\n */\nexport function pushSidecarManifest(opts: {\n sidecarRepoUrl: string;\n manifestText: string;\n spawn?: SpawnLike;\n}): { commitSha: string } {\n const spawn = opts.spawn ?? spawnSync;\n // Dedicated dir next to the source clone cache; wipe any stale clone first so\n // a re-publish always starts from a clean shallow checkout of the remote.\n const cloneDir = `${sourceClonePath(sourceCacheKey(opts.sidecarRepoUrl))}-sidecar-push`;\n rmSync(cloneDir, { recursive: true, force: true });\n mkdirSync(dirname(cloneDir), { recursive: true });\n\n // The clone is scratch — always remove it afterwards (success or failure) so a\n // failed push never leaves a stale checkout in the cache dir.\n try {\n const cloneRes = spawn(\"git\", [\"clone\", \"--depth\", \"1\", opts.sidecarRepoUrl, cloneDir], {\n encoding: \"utf-8\",\n });\n if (cloneRes.status !== 0) {\n const stderr = (cloneRes.stderr ?? \"\").toString().trim();\n throw new Error(\n `git clone ${opts.sidecarRepoUrl} failed: ${stderr || `exit ${cloneRes.status}`}`,\n );\n }\n\n writeFileSync(join(cloneDir, SIDECAR_MANIFEST_FILENAME), opts.manifestText, \"utf-8\");\n git(spawn, cloneDir, [\"add\", SIDECAR_MANIFEST_FILENAME]);\n\n // Fixed bot identity via -c so the commit succeeds regardless of the curator's\n // git config (the sidecar push is a machine action, not authored work).\n const commitRes = spawn(\n \"git\",\n [\n \"-C\",\n cloneDir,\n \"-c\",\n \"user.email=publish@skaile.store\",\n \"-c\",\n \"user.name=skaile\",\n \"commit\",\n \"-m\",\n \"chore(sidecar): publish curated manifest\",\n ],\n { encoding: \"utf-8\" },\n );\n if (commitRes.status !== 0) {\n const out = `${commitRes.stdout ?? \"\"}${commitRes.stderr ?? \"\"}`;\n // Nothing changed → idempotent re-publish; keep the existing HEAD.\n if (!/nothing to commit/i.test(out)) {\n throw new Error(`git commit failed: ${out.trim() || `exit ${commitRes.status}`}`);\n }\n } else {\n // `push origin HEAD` (not a bare `push`) so a fresh sidecar repo with an\n // unborn/renamed default branch still gets its branch created on the remote.\n git(spawn, cloneDir, [\"push\", \"origin\", \"HEAD\"]);\n }\n\n return { commitSha: git(spawn, cloneDir, [\"rev-parse\", \"HEAD\"]) };\n } finally {\n rmSync(cloneDir, { recursive: true, force: true });\n }\n}\n\n// ── Orchestration ───────────────────────────────────────────────────────────\n\n/**\n * `source manifest publish <src>` — publish a curated sidecar manifest to the\n * store. See the module header for the full flow. Store calls go through\n * `client` (default HTTP); git side-effects through `spawn` (default\n * `spawnSync`). The auth gate is enforced only for the default HTTP client so\n * injected fakes bypass it.\n */\nexport async function runPublish(\n arg: string,\n opts: {\n projectDir: string;\n as?: string;\n sidecarRepo?: string;\n ref?: string;\n dryRun?: boolean;\n },\n client?: PublisherClient,\n spawn: SpawnLike = spawnSync,\n): Promise<void> {\n const injected = client !== undefined;\n const pub = client ?? makeHttpPublisherClient();\n\n const { url, slug, manifestFile } = resolveSourceArg(arg, opts.projectDir);\n\n if (!existsSync(manifestFile)) {\n logErr(\n `No curated manifest for \"${slug}\" at ${S.dim(manifestFile)} — ` +\n \"run `skaile source manifest init` first.\",\n );\n process.exit(1);\n }\n\n const { manifest, diagnostics } = decodeSkaileManifest(readFileSync(manifestFile, \"utf-8\"));\n if (diagnostics.some((d) => d.severity === \"error\")) {\n for (const d of diagnostics.filter((x) => x.severity === \"error\")) {\n logErr(`${d.code}: ${d.message}`);\n }\n logErr(\n \"The curated manifest has errors — fix them with `skaile source manifest edit` / \" +\n \"`verify` before publishing.\",\n );\n process.exit(1);\n }\n\n // A real publish makes store calls (+ `me()` when `--as` is omitted), so it\n // needs a token. `--dry-run` is an offline preview: never gate it on auth.\n const authed = injected || isStoreAuthenticated();\n if (!opts.dryRun && !authed) {\n logErr(\"Not signed in — run `skaile store login` first.\");\n process.exit(1);\n }\n\n // Namespace: `--as` wins; else the signed-in username. In an unauthenticated\n // dry-run we cannot call `me()`, so show a placeholder in the offline plan.\n let namespace: string;\n if (opts.as) namespace = opts.as;\n else if (authed) namespace = (await pub.me()).username;\n else namespace = \"<your store username>\";\n\n const normalized = normalizePublishedManifest(manifest, namespace);\n const publishedText = encodeSkaileManifest(normalized);\n\n const wouldBeRefs = (normalized.assets ?? []).map((a) =>\n refFor(a.kind, namespace, a.name, a.version ?? normalized.version),\n );\n\n if (opts.dryRun) {\n const sidecar = opts.sidecarRepo ?? getSidecarRepo(slug) ?? \"<none — pass --sidecar-repo>\";\n logInfo(`Publish plan for ${S.bold(slug)}:`);\n logInfo(` namespace: ${namespace}`);\n logInfo(` sidecar repo: ${sidecar}`);\n logInfo(` source ref: ${opts.ref ?? \"main\"}`);\n logInfo(` would publish ${wouldBeRefs.length} asset(s):`);\n for (const r of wouldBeRefs) logInfo(` ${r}`);\n return;\n }\n\n const sidecarRepoUrl = opts.sidecarRepo ?? getSidecarRepo(slug);\n if (!sidecarRepoUrl) {\n logErr(\n \"No sidecar repo associated with this source. Pass \" +\n `${S.cmd(\"--sidecar-repo https://github.com/<you>/<repo>\")} — it must be a ` +\n \"PUBLIC GitHub repo you own; the curated manifest is committed there and the \" +\n \"store pins to that commit.\",\n );\n process.exit(1);\n }\n if (opts.sidecarRepo) saveSidecarRepo(slug, sidecarRepoUrl);\n\n const { commitSha } = pushSidecarManifest({ sidecarRepoUrl, manifestText: publishedText, spawn });\n logOk(`Pushed curated manifest to ${S.dim(sidecarRepoUrl)} @ ${commitSha.slice(0, 10)}.`);\n\n // The FOREIGN repo's ref to ingest (branch/sha). Defaults to `main`.\n const sourceRef = opts.ref ?? \"main\";\n\n const { published } = await publishToStore({\n sourceUrl: url,\n ref: sourceRef,\n sidecar: { url: sidecarRepoUrl, ref: commitSha },\n manifest: normalized,\n client: pub,\n });\n\n if (published.length > 0) {\n logInfo(`Consumers can now install them with \\`skaile add ${published[0]}\\`.`);\n }\n}\n\n/**\n * `source manifest yank <src>` — unpublish the source's published assets (all,\n * or the single asset matching `opts.asset`'s name). Auth-gated like publish.\n */\nexport async function runYank(\n arg: string,\n opts: { projectDir: string; asset?: string },\n client?: PublisherClient,\n): Promise<void> {\n const injected = client !== undefined;\n const pub = client ?? makeHttpPublisherClient();\n\n const { url, slug } = resolveSourceArg(arg, opts.projectDir);\n\n if (!injected && !isStoreAuthenticated()) {\n logErr(\"Not signed in — run `skaile store login` first.\");\n process.exit(1);\n }\n\n const rows = await pub.sourcesList();\n const source = rows.find((r) => r.url === url);\n if (!source) {\n logErr(`Source \"${slug}\" is not registered in the store — nothing to yank.`);\n process.exit(1);\n }\n\n // Optionally narrow to a single asset by name (accept a bare name or a ref).\n const targetName = opts.asset ? bareName(opts.asset) : undefined;\n const candidates = (await pub.sourceCandidates(source.id)).filter(\n (c) => c.published && (!targetName || c.name === targetName),\n );\n if (candidates.length === 0) {\n logWarn(\"No published assets matched — nothing to yank.\");\n return;\n }\n\n const yanked: string[] = [];\n for (const c of candidates) {\n try {\n await pub.assetUnpublish(c.id);\n yanked.push(`${c.kind}:${c.name}`);\n } catch (err) {\n logWarn(\n `Failed to yank ${c.kind}:${c.name}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n logOk(`Yanked ${yanked.length} asset(s):`);\n for (const r of yanked) logInfo(` ${r}`);\n}\n"]}