@vm0/cli 9.238.3 → 9.238.5

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 (144) hide show
  1. package/{agent-CTMIX4TA.js → agent-KS3ULPSZ.js} +6 -8
  2. package/{agent-CTMIX4TA.js.map → agent-KS3ULPSZ.js.map} +1 -1
  3. package/{banking-7EIKU7WX.js → banking-2B3GDOIE.js} +4 -6
  4. package/{banking-7EIKU7WX.js.map → banking-2B3GDOIE.js.map} +1 -1
  5. package/bill.generated-5FJHQPXY.js +16 -0
  6. package/bill.generated-5FJHQPXY.js.map +1 -0
  7. package/bill.generated-HYFQCA2Q.js +16 -0
  8. package/bill.generated-HYFQCA2Q.js.map +1 -0
  9. package/{chat-5MN7N3LD.js → chat-HP7XYF7H.js} +5 -7
  10. package/{chat-5MN7N3LD.js.map → chat-HP7XYF7H.js.map} +1 -1
  11. package/{chunk-65ZW3GHG.js → chunk-EJBHYDGP.js} +5 -7
  12. package/{chunk-65ZW3GHG.js.map → chunk-EJBHYDGP.js.map} +1 -1
  13. package/{chunk-XX3HVOWG.js → chunk-GIACTMOF.js} +18 -1015
  14. package/chunk-GIACTMOF.js.map +1 -0
  15. package/{chunk-ADBNTM34.js → chunk-H4Y7JDZB.js} +1947 -78
  16. package/chunk-H4Y7JDZB.js.map +1 -0
  17. package/{chunk-3LJFZEZ5.js → chunk-OCOHCUE3.js} +922 -290
  18. package/chunk-OCOHCUE3.js.map +1 -0
  19. package/{chunk-NAFRQSTL.js → chunk-T3XOMNS6.js} +3 -3
  20. package/{chunk-3SWR53IF.js → chunk-TEJZT6KB.js} +4 -4
  21. package/{chunk-3SZJPIMX.js → chunk-UHVWYX44.js} +2 -2
  22. package/{chunk-22VWTDX6.js → chunk-VC7E6IA7.js} +2830 -1325
  23. package/chunk-VC7E6IA7.js.map +1 -0
  24. package/{chunk-WPUM3KGN.js → chunk-VUER2HGS.js} +2 -2
  25. package/{chunk-4ODVSQ6H.js → chunk-YQ5ZYQN3.js} +2 -2
  26. package/{computer-use-JW6NHZFY.js → computer-use-6GZVM5S6.js} +3 -4
  27. package/{computer-use-JW6NHZFY.js.map → computer-use-6GZVM5S6.js.map} +1 -1
  28. package/{connector-II52GGER.js → connector-SFMD6HBQ.js} +5 -7
  29. package/{connector-II52GGER.js.map → connector-SFMD6HBQ.js.map} +1 -1
  30. package/copper.generated-PZRA3BV7.js +16 -0
  31. package/copper.generated-PZRA3BV7.js.map +1 -0
  32. package/copper.generated-UBWQDA5K.js +16 -0
  33. package/copper.generated-UBWQDA5K.js.map +1 -0
  34. package/{credit-SDMLLER2.js → credit-B465R4TF.js} +5 -7
  35. package/{credit-SDMLLER2.js.map → credit-B465R4TF.js.map} +1 -1
  36. package/datadog.generated-S4YB2V57.js +16 -0
  37. package/datadog.generated-S4YB2V57.js.map +1 -0
  38. package/datadog.generated-Z3O2DYLP.js +16 -0
  39. package/datadog.generated-Z3O2DYLP.js.map +1 -0
  40. package/{developer-support-7OGYYIJ2.js → developer-support-6GM2UW5P.js} +3 -4
  41. package/{developer-support-7OGYYIJ2.js.map → developer-support-6GM2UW5P.js.map} +1 -1
  42. package/{doctor-UJIIOA33.js → doctor-Z3HFRIKJ.js} +104 -18
  43. package/doctor-Z3HFRIKJ.js.map +1 -0
  44. package/expensify.generated-G2ZGBKBQ.js +16 -0
  45. package/expensify.generated-G2ZGBKBQ.js.map +1 -0
  46. package/expensify.generated-OHAW3AHP.js +16 -0
  47. package/expensify.generated-OHAW3AHP.js.map +1 -0
  48. package/{generate-DPGQKZTH.js → generate-37CJMAVG.js} +5 -7
  49. package/{generate-DPGQKZTH.js.map → generate-37CJMAVG.js.map} +1 -1
  50. package/{github-DA62AJIQ.js → github-6CSR7332.js} +3 -4
  51. package/{github-DA62AJIQ.js.map → github-6CSR7332.js.map} +1 -1
  52. package/{goal-WWM7OYBQ.js → goal-XURMW5OS.js} +3 -4
  53. package/{goal-WWM7OYBQ.js.map → goal-XURMW5OS.js.map} +1 -1
  54. package/google-contacts.generated-FL6Z7MTD.js +16 -0
  55. package/google-contacts.generated-FL6Z7MTD.js.map +1 -0
  56. package/google-contacts.generated-Q67YBTPW.js +16 -0
  57. package/google-contacts.generated-Q67YBTPW.js.map +1 -0
  58. package/google-forms.generated-AOKO24AB.js +16 -0
  59. package/google-forms.generated-AOKO24AB.js.map +1 -0
  60. package/google-forms.generated-KDCHIV43.js +16 -0
  61. package/google-forms.generated-KDCHIV43.js.map +1 -0
  62. package/{host-YMKJGV6R.js → host-EVFNV5BX.js} +4 -6
  63. package/{host-YMKJGV6R.js.map → host-EVFNV5BX.js.map} +1 -1
  64. package/index.js +14 -17
  65. package/index.js.map +1 -1
  66. package/{logs-FKXVE6QD.js → logs-DR7ZTWBK.js} +7 -10
  67. package/{logs-FKXVE6QD.js.map → logs-DR7ZTWBK.js.map} +1 -1
  68. package/{maps-MWMFHA72.js → maps-IAVJJMRT.js} +4 -6
  69. package/{maps-MWMFHA72.js.map → maps-IAVJJMRT.js.map} +1 -1
  70. package/{memory-KAGWT3GE.js → memory-X765S3ZI.js} +4 -6
  71. package/{memory-KAGWT3GE.js.map → memory-X765S3ZI.js.map} +1 -1
  72. package/{model-67UDE3IM.js → model-ZYVNUG47.js} +6 -8
  73. package/{model-67UDE3IM.js.map → model-ZYVNUG47.js.map} +1 -1
  74. package/{model-provider-YGNGMT6S.js → model-provider-SZIIRXS3.js} +5 -7
  75. package/{model-provider-YGNGMT6S.js.map → model-provider-SZIIRXS3.js.map} +1 -1
  76. package/netsuite.generated-3NXSZOXT.js +16 -0
  77. package/netsuite.generated-3NXSZOXT.js.map +1 -0
  78. package/netsuite.generated-XV3WXA4I.js +16 -0
  79. package/netsuite.generated-XV3WXA4I.js.map +1 -0
  80. package/{org-L52CQ6HJ.js → org-GBDLJZSE.js} +10 -12
  81. package/{org-L52CQ6HJ.js.map → org-GBDLJZSE.js.map} +1 -1
  82. package/package.json +1 -1
  83. package/paypal.generated-MDKROCJG.js +16 -0
  84. package/paypal.generated-MDKROCJG.js.map +1 -0
  85. package/paypal.generated-YZYYL7HX.js +16 -0
  86. package/paypal.generated-YZYYL7HX.js.map +1 -0
  87. package/{phone-VYQKHTRX.js → phone-KA4NZFQC.js} +4 -6
  88. package/{phone-VYQKHTRX.js.map → phone-KA4NZFQC.js.map} +1 -1
  89. package/{preference-7ULJO7RD.js → preference-TEMJHA73.js} +4 -6
  90. package/{preference-7ULJO7RD.js.map → preference-TEMJHA73.js.map} +1 -1
  91. package/ramp.generated-GDRLFPGX.js +16 -0
  92. package/ramp.generated-GDRLFPGX.js.map +1 -0
  93. package/ramp.generated-RJKZQLIG.js +16 -0
  94. package/ramp.generated-RJKZQLIG.js.map +1 -0
  95. package/{relationship-TNCKBWUW.js → relationship-OXV2SPNL.js} +4 -6
  96. package/{relationship-TNCKBWUW.js.map → relationship-OXV2SPNL.js.map} +1 -1
  97. package/{resource-V4AXTBFL.js → resource-2WREU3GR.js} +4 -6
  98. package/{resource-V4AXTBFL.js.map → resource-2WREU3GR.js.map} +1 -1
  99. package/{search-ABCFRK5K.js → search-V5V5IHY7.js} +7 -10
  100. package/{search-ABCFRK5K.js.map → search-V5V5IHY7.js.map} +1 -1
  101. package/{secret-6C53IEKW.js → secret-LIAHG47P.js} +12 -26
  102. package/secret-LIAHG47P.js.map +1 -0
  103. package/{slack-H4OQPL4A.js → slack-BUOXO2HU.js} +4 -6
  104. package/{slack-H4OQPL4A.js.map → slack-BUOXO2HU.js.map} +1 -1
  105. package/{teams-RLQBP3SK.js → teams-G7TYHRJB.js} +4 -6
  106. package/{teams-RLQBP3SK.js.map → teams-G7TYHRJB.js.map} +1 -1
  107. package/{telegram-TKQOVOWL.js → telegram-DEHNZSEN.js} +4 -6
  108. package/{telegram-TKQOVOWL.js.map → telegram-DEHNZSEN.js.map} +1 -1
  109. package/{variable-5PRGXPQX.js → variable-RMYF6NVZ.js} +4 -6
  110. package/{variable-5PRGXPQX.js.map → variable-RMYF6NVZ.js.map} +1 -1
  111. package/{video-CVM7TXWW.js → video-XEYMVSIU.js} +2 -3
  112. package/{video-CVM7TXWW.js.map → video-XEYMVSIU.js.map} +1 -1
  113. package/{web-E3KRU54R.js → web-4REDKON3.js} +3 -4
  114. package/{web-E3KRU54R.js.map → web-4REDKON3.js.map} +1 -1
  115. package/{whoami-7JOZNZEZ.js → whoami-66W7DPQX.js} +6 -8
  116. package/{whoami-7JOZNZEZ.js.map → whoami-66W7DPQX.js.map} +1 -1
  117. package/workday.generated-4MPT7O3V.js +16 -0
  118. package/workday.generated-4MPT7O3V.js.map +1 -0
  119. package/workday.generated-AHL44LEE.js +16 -0
  120. package/workday.generated-AHL44LEE.js.map +1 -0
  121. package/{workflow-RAR37LR4.js → workflow-PBJVC6HV.js} +5 -7
  122. package/workflow-PBJVC6HV.js.map +1 -0
  123. package/zero.js +34 -51
  124. package/zero.js.map +1 -1
  125. package/automation-7MAK66QT.js +0 -31
  126. package/automation-7MAK66QT.js.map +0 -1
  127. package/chunk-22VWTDX6.js.map +0 -1
  128. package/chunk-3LJFZEZ5.js.map +0 -1
  129. package/chunk-ADBNTM34.js.map +0 -1
  130. package/chunk-JUTUEPIR.js +0 -512
  131. package/chunk-JUTUEPIR.js.map +0 -1
  132. package/chunk-NBAZLPV3.js +0 -1301
  133. package/chunk-NBAZLPV3.js.map +0 -1
  134. package/chunk-XX3HVOWG.js.map +0 -1
  135. package/doctor-UJIIOA33.js.map +0 -1
  136. package/schedule-OSHL7HWT.js +0 -33
  137. package/schedule-OSHL7HWT.js.map +0 -1
  138. package/secret-6C53IEKW.js.map +0 -1
  139. package/workflow-RAR37LR4.js.map +0 -1
  140. /package/{chunk-NAFRQSTL.js.map → chunk-T3XOMNS6.js.map} +0 -0
  141. /package/{chunk-3SWR53IF.js.map → chunk-TEJZT6KB.js.map} +0 -0
  142. /package/{chunk-3SZJPIMX.js.map → chunk-UHVWYX44.js.map} +0 -0
  143. /package/{chunk-WPUM3KGN.js.map → chunk-VUER2HGS.js.map} +0 -0
  144. /package/{chunk-4ODVSQ6H.js.map → chunk-YQ5ZYQN3.js.map} +0 -0
@@ -5,12 +5,11 @@ import {
5
5
  completeGithubFileUpload,
6
6
  downloadGithubFile,
7
7
  initGithubFileUpload
8
- } from "./chunk-XX3HVOWG.js";
8
+ } from "./chunk-GIACTMOF.js";
9
9
  import "./chunk-LTDQISD7.js";
10
10
  import {
11
11
  withErrorHandler
12
- } from "./chunk-22VWTDX6.js";
13
- import "./chunk-JUTUEPIR.js";
12
+ } from "./chunk-VC7E6IA7.js";
14
13
  import "./chunk-LRHXR7JT.js";
15
14
  import {
16
15
  Command
@@ -201,4 +200,4 @@ Examples:
201
200
  export {
202
201
  zeroGithubCommand
203
202
  };
204
- //# sourceMappingURL=github-DA62AJIQ.js.map
203
+ //# sourceMappingURL=github-6CSR7332.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/zero/github/index.ts","../src/commands/zero/github/download-file.ts","../src/commands/zero/github/upload-file.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { downloadFileCommand } from \"./download-file\";\nimport { uploadFileCommand } from \"./upload-file\";\n\nexport const zeroGithubCommand = new Command()\n .name(\"github\")\n .description(\"Upload and download GitHub files\")\n .addCommand(downloadFileCommand)\n .addCommand(uploadFileCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n Upload a file: zero github upload-file -f /tmp/report.pdf -r vm0-ai/vm0 -i 42\n Download a file: zero github download-file https://github.com/user-attachments/assets/abc123 -o /tmp/out.png`,\n );\n","import { basename, join } from \"path\";\nimport { tmpdir } from \"os\";\nimport { Command } from \"commander\";\nimport { downloadGithubFile } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nfunction filenameFromUrl(fileUrl: string): string {\n if (URL.canParse(fileUrl)) {\n const segment = new URL(fileUrl).pathname.split(\"/\").filter(Boolean).pop();\n if (!segment) {\n return \"file\";\n }\n try {\n return decodeURIComponent(segment);\n } catch {\n return segment;\n }\n }\n return basename(fileUrl) || \"file\";\n}\n\nfunction safeDefaultFilename(filename: string): string {\n const component = basename(filename.replaceAll(\"\\\\\", \"/\"));\n if (!component || component === \".\" || component === \"..\") {\n return \"file\";\n }\n return component;\n}\n\nfunction defaultOutPath(fileUrl: string, filename?: string): string {\n return join(\n tmpdir(),\n `github-${safeDefaultFilename(filename || filenameFromUrl(fileUrl))}`,\n );\n}\n\nexport const downloadFileCommand = new Command()\n .name(\"download-file\")\n .description(\"Download a file from a GitHub context block\")\n .argument(\"<url>\", \"URL from a [GitHub file] block\")\n .option(\n \"-o, --out <path>\",\n \"Output path for the downloaded file (default: /tmp/github-<filename-or-url-basename>)\",\n )\n .option(\"--filename <name>\", \"Filename hint from the [GitHub file] block\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Download to default temp path: zero github download-file https://github.com/user-attachments/assets/abc123 --filename screenshot.png\n Download to explicit path: zero github download-file https://github.com/user-attachments/assets/abc123 -o /tmp/screenshot.png\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"path\":\"/tmp/github-screenshot.png\",\"mimetype\":\"image/png\",\"size\":12345}\n\nHow to read the downloaded file:\n - Images (png/jpg/gif/webp/svg): open the file path with your image viewing tool\n - Videos (mp4/mov/webm): transcribe audio first with\n zero video transcribe --url <download-url>\n or extract frames with\n ffmpeg -i <path> -vf \"fps=1\" -q:v 2 /tmp/github_frame_%03d.jpg\n - PDF/text/csv/json/markdown: read the file directly\n\nNotes:\n - The URL comes from a [GitHub file] block\n - Streams the GitHub file bytes through VM0 directly to disk`,\n )\n .action(\n withErrorHandler(\n async (fileUrl: string, options: { out?: string; filename?: string }) => {\n const outPath =\n options.out ?? defaultOutPath(fileUrl, options.filename);\n const result = await downloadGithubFile(\n fileUrl,\n outPath,\n options.filename,\n );\n console.log(JSON.stringify(result));\n },\n ),\n );\n","import { readFileSync, statSync } from \"fs\";\nimport { basename, extname } from \"path\";\nimport { Command } from \"commander\";\nimport {\n completeGithubFileUpload,\n initGithubFileUpload,\n} from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nconst MIME_BY_EXTENSION: Record<string, string> = {\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".mp4\": \"video/mp4\",\n \".webm\": \"video/webm\",\n \".mov\": \"video/quicktime\",\n \".pdf\": \"application/pdf\",\n \".txt\": \"text/plain\",\n \".csv\": \"text/csv\",\n \".md\": \"text/markdown\",\n \".json\": \"application/json\",\n};\n\nfunction inferContentType(localPath: string): string {\n const ext = extname(localPath).toLowerCase();\n return MIME_BY_EXTENSION[ext] ?? \"application/octet-stream\";\n}\n\nfunction parseIssueNumber(value: string): number {\n const parsed = Number(value);\n if (!Number.isSafeInteger(parsed) || parsed <= 0) {\n throw new Error(\"issue-number must be a positive integer\");\n }\n return parsed;\n}\n\nexport const uploadFileCommand = new Command()\n .name(\"upload-file\")\n .description(\"Upload a local file to a GitHub issue or pull request comment\")\n .requiredOption(\"-f, --file <path>\", \"Local file path to upload\")\n .requiredOption(\"-r, --repo <owner/name>\", \"GitHub repository\")\n .requiredOption(\n \"-i, --issue-number <number>\",\n \"GitHub issue or pull request number\",\n )\n .option(\"--caption <text>\", \"Text to include before the file link\")\n .option(\"--content-type <mime>\", \"Override inferred content type\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Upload a file: zero github upload-file -f /tmp/report.pdf -r vm0-ai/vm0 -i 42\n With a caption: zero github upload-file -f /tmp/data.csv -r vm0-ai/vm0 -i 42 --caption \"Daily report\"\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"commentId\":\"123\",\"repo\":\"vm0-ai/vm0\",\"issueNumber\":42,\"filename\":\"report.pdf\",\"mimetype\":\"application/pdf\",\"size\":12345,\"url\":\"https://...\"}\n\nNotes:\n - Uses the GitHub App installation on the server side\n - Uploads through VM0 storage first, then posts a GitHub comment containing the file URL`,\n )\n .action(\n withErrorHandler(\n async (options: {\n file: string;\n repo: string;\n issueNumber: string;\n caption?: string;\n contentType?: string;\n }) => {\n let fileSize: number;\n try {\n const stat = statSync(options.file);\n if (!stat.isFile()) {\n throw new Error(`Not a regular file: ${options.file}`);\n }\n fileSize = stat.size;\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"Not \")) {\n throw error;\n }\n throw new Error(`File not found: ${options.file}`);\n }\n\n if (fileSize === 0) {\n throw new Error(\"File is empty\");\n }\n\n const filename = basename(options.file);\n const contentType =\n options.contentType ?? inferContentType(options.file);\n const issueNumber = parseIssueNumber(options.issueNumber);\n\n const prepared = await initGithubFileUpload({\n filename,\n contentType,\n length: fileSize,\n });\n\n const fileContent = readFileSync(options.file);\n const uploadResponse = await fetch(prepared.uploadUrl, {\n method: \"PUT\",\n headers: { \"Content-Type\": prepared.contentType },\n body: new Uint8Array(fileContent),\n });\n\n if (!uploadResponse.ok) {\n throw new Error(\n `File upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`,\n );\n }\n\n const result = await completeGithubFileUpload({\n uploadId: prepared.uploadId,\n repo: options.repo,\n issueNumber,\n contentType: prepared.contentType,\n caption: options.caption,\n });\n\n console.log(JSON.stringify(result));\n },\n ),\n );\n"],"mappings":"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","names":["basename","basename"]}
1
+ {"version":3,"sources":["../src/commands/zero/github/index.ts","../src/commands/zero/github/download-file.ts","../src/commands/zero/github/upload-file.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { downloadFileCommand } from \"./download-file\";\nimport { uploadFileCommand } from \"./upload-file\";\n\nexport const zeroGithubCommand = new Command()\n .name(\"github\")\n .description(\"Upload and download GitHub files\")\n .addCommand(downloadFileCommand)\n .addCommand(uploadFileCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n Upload a file: zero github upload-file -f /tmp/report.pdf -r vm0-ai/vm0 -i 42\n Download a file: zero github download-file https://github.com/user-attachments/assets/abc123 -o /tmp/out.png`,\n );\n","import { basename, join } from \"path\";\nimport { tmpdir } from \"os\";\nimport { Command } from \"commander\";\nimport { downloadGithubFile } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nfunction filenameFromUrl(fileUrl: string): string {\n if (URL.canParse(fileUrl)) {\n const segment = new URL(fileUrl).pathname.split(\"/\").filter(Boolean).pop();\n if (!segment) {\n return \"file\";\n }\n try {\n return decodeURIComponent(segment);\n } catch {\n return segment;\n }\n }\n return basename(fileUrl) || \"file\";\n}\n\nfunction safeDefaultFilename(filename: string): string {\n const component = basename(filename.replaceAll(\"\\\\\", \"/\"));\n if (!component || component === \".\" || component === \"..\") {\n return \"file\";\n }\n return component;\n}\n\nfunction defaultOutPath(fileUrl: string, filename?: string): string {\n return join(\n tmpdir(),\n `github-${safeDefaultFilename(filename || filenameFromUrl(fileUrl))}`,\n );\n}\n\nexport const downloadFileCommand = new Command()\n .name(\"download-file\")\n .description(\"Download a file from a GitHub context block\")\n .argument(\"<url>\", \"URL from a [GitHub file] block\")\n .option(\n \"-o, --out <path>\",\n \"Output path for the downloaded file (default: /tmp/github-<filename-or-url-basename>)\",\n )\n .option(\"--filename <name>\", \"Filename hint from the [GitHub file] block\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Download to default temp path: zero github download-file https://github.com/user-attachments/assets/abc123 --filename screenshot.png\n Download to explicit path: zero github download-file https://github.com/user-attachments/assets/abc123 -o /tmp/screenshot.png\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"path\":\"/tmp/github-screenshot.png\",\"mimetype\":\"image/png\",\"size\":12345}\n\nHow to read the downloaded file:\n - Images (png/jpg/gif/webp/svg): open the file path with your image viewing tool\n - Videos (mp4/mov/webm): transcribe audio first with\n zero video transcribe --url <download-url>\n or extract frames with\n ffmpeg -i <path> -vf \"fps=1\" -q:v 2 /tmp/github_frame_%03d.jpg\n - PDF/text/csv/json/markdown: read the file directly\n\nNotes:\n - The URL comes from a [GitHub file] block\n - Streams the GitHub file bytes through VM0 directly to disk`,\n )\n .action(\n withErrorHandler(\n async (fileUrl: string, options: { out?: string; filename?: string }) => {\n const outPath =\n options.out ?? defaultOutPath(fileUrl, options.filename);\n const result = await downloadGithubFile(\n fileUrl,\n outPath,\n options.filename,\n );\n console.log(JSON.stringify(result));\n },\n ),\n );\n","import { readFileSync, statSync } from \"fs\";\nimport { basename, extname } from \"path\";\nimport { Command } from \"commander\";\nimport {\n completeGithubFileUpload,\n initGithubFileUpload,\n} from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nconst MIME_BY_EXTENSION: Record<string, string> = {\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".mp4\": \"video/mp4\",\n \".webm\": \"video/webm\",\n \".mov\": \"video/quicktime\",\n \".pdf\": \"application/pdf\",\n \".txt\": \"text/plain\",\n \".csv\": \"text/csv\",\n \".md\": \"text/markdown\",\n \".json\": \"application/json\",\n};\n\nfunction inferContentType(localPath: string): string {\n const ext = extname(localPath).toLowerCase();\n return MIME_BY_EXTENSION[ext] ?? \"application/octet-stream\";\n}\n\nfunction parseIssueNumber(value: string): number {\n const parsed = Number(value);\n if (!Number.isSafeInteger(parsed) || parsed <= 0) {\n throw new Error(\"issue-number must be a positive integer\");\n }\n return parsed;\n}\n\nexport const uploadFileCommand = new Command()\n .name(\"upload-file\")\n .description(\"Upload a local file to a GitHub issue or pull request comment\")\n .requiredOption(\"-f, --file <path>\", \"Local file path to upload\")\n .requiredOption(\"-r, --repo <owner/name>\", \"GitHub repository\")\n .requiredOption(\n \"-i, --issue-number <number>\",\n \"GitHub issue or pull request number\",\n )\n .option(\"--caption <text>\", \"Text to include before the file link\")\n .option(\"--content-type <mime>\", \"Override inferred content type\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Upload a file: zero github upload-file -f /tmp/report.pdf -r vm0-ai/vm0 -i 42\n With a caption: zero github upload-file -f /tmp/data.csv -r vm0-ai/vm0 -i 42 --caption \"Daily report\"\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"commentId\":\"123\",\"repo\":\"vm0-ai/vm0\",\"issueNumber\":42,\"filename\":\"report.pdf\",\"mimetype\":\"application/pdf\",\"size\":12345,\"url\":\"https://...\"}\n\nNotes:\n - Uses the GitHub App installation on the server side\n - Uploads through VM0 storage first, then posts a GitHub comment containing the file URL`,\n )\n .action(\n withErrorHandler(\n async (options: {\n file: string;\n repo: string;\n issueNumber: string;\n caption?: string;\n contentType?: string;\n }) => {\n let fileSize: number;\n try {\n const stat = statSync(options.file);\n if (!stat.isFile()) {\n throw new Error(`Not a regular file: ${options.file}`);\n }\n fileSize = stat.size;\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"Not \")) {\n throw error;\n }\n throw new Error(`File not found: ${options.file}`);\n }\n\n if (fileSize === 0) {\n throw new Error(\"File is empty\");\n }\n\n const filename = basename(options.file);\n const contentType =\n options.contentType ?? inferContentType(options.file);\n const issueNumber = parseIssueNumber(options.issueNumber);\n\n const prepared = await initGithubFileUpload({\n filename,\n contentType,\n length: fileSize,\n });\n\n const fileContent = readFileSync(options.file);\n const uploadResponse = await fetch(prepared.uploadUrl, {\n method: \"PUT\",\n headers: { \"Content-Type\": prepared.contentType },\n body: new Uint8Array(fileContent),\n });\n\n if (!uploadResponse.ok) {\n throw new Error(\n `File upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`,\n );\n }\n\n const result = await completeGithubFileUpload({\n uploadId: prepared.uploadId,\n repo: options.repo,\n issueNumber,\n contentType: prepared.contentType,\n caption: options.caption,\n });\n\n console.log(JSON.stringify(result));\n },\n ),\n );\n"],"mappings":"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","names":["basename","basename"]}
@@ -10,12 +10,11 @@ import {
10
10
  getGoal,
11
11
  pauseGoal,
12
12
  resumeGoal
13
- } from "./chunk-XX3HVOWG.js";
13
+ } from "./chunk-GIACTMOF.js";
14
14
  import "./chunk-LTDQISD7.js";
15
15
  import {
16
16
  withErrorHandler
17
- } from "./chunk-22VWTDX6.js";
18
- import "./chunk-JUTUEPIR.js";
17
+ } from "./chunk-VC7E6IA7.js";
19
18
  import "./chunk-LRHXR7JT.js";
20
19
  import {
21
20
  Command
@@ -78,4 +77,4 @@ var zeroGoalCommand = new Command().name("goal").description("Manage the current
78
77
  export {
79
78
  zeroGoalCommand
80
79
  };
81
- //# sourceMappingURL=goal-WWM7OYBQ.js.map
80
+ //# sourceMappingURL=goal-XURMW5OS.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/zero/goal/index.ts"],"sourcesContent":["import { Command } from \"commander\";\n\nimport {\n blockGoal,\n clearGoal,\n completeGoal,\n createGoal,\n editGoal,\n getGoal,\n pauseGoal,\n resumeGoal,\n} from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\ninterface CreateOptions {\n readonly objective: string;\n}\n\ninterface EditOptions {\n readonly objective: string;\n}\n\nfunction printJson(value: unknown): void {\n console.log(JSON.stringify(value));\n}\n\nconst createCommand = new Command()\n .name(\"create\")\n .description(\n \"Create a persistent goal for the current thread. Create a goal ONLY when the user explicitly asks for a persistent, autonomous, cross-turn task; do not infer a goal from an ordinary one-off request.\",\n )\n .requiredOption(\n \"--objective <text>\",\n \"Goal objective. Set a goal ONLY on an explicit user request for autonomous cross-turn work; never infer one from a one-off request.\",\n )\n .action(\n withErrorHandler(async (options: CreateOptions) => {\n printJson(await createGoal({ objective: options.objective }));\n }),\n );\n\nconst editCommand = new Command()\n .name(\"edit\")\n .description(\"Edit the current thread goal objective\")\n .requiredOption(\"--objective <text>\", \"New goal objective\")\n .action(\n withErrorHandler(async (options: EditOptions) => {\n printJson(await editGoal({ objective: options.objective }));\n }),\n );\n\nconst getCommand = new Command()\n .name(\"get\")\n .description(\"Get the current thread goal\")\n .action(\n withErrorHandler(async () => {\n printJson(await getGoal());\n }),\n );\n\nconst completeCommand = new Command()\n .name(\"complete\")\n .description(\"Mark the current thread goal complete\")\n .action(\n withErrorHandler(async () => {\n printJson(await completeGoal());\n }),\n );\n\nconst blockCommand = new Command()\n .name(\"block\")\n .description(\"Mark the current thread goal blocked\")\n .action(\n withErrorHandler(async () => {\n printJson(await blockGoal());\n }),\n );\n\nconst pauseCommand = new Command()\n .name(\"pause\")\n .description(\"Pause the current thread goal\")\n .action(\n withErrorHandler(async () => {\n printJson(await pauseGoal());\n }),\n );\n\nconst resumeCommand = new Command()\n .name(\"resume\")\n .description(\"Resume continuation for the current thread goal\")\n .action(\n withErrorHandler(async () => {\n printJson(await resumeGoal());\n }),\n );\n\nconst clearCommand = new Command()\n .name(\"clear\")\n .description(\"Clear the current thread goal\")\n .action(\n withErrorHandler(async () => {\n printJson(await clearGoal());\n }),\n );\n\nexport const zeroGoalCommand = new Command()\n .name(\"goal\")\n .description(\"Manage the current thread goal\")\n .addCommand(createCommand)\n .addCommand(editCommand)\n .addCommand(getCommand)\n .addCommand(completeCommand)\n .addCommand(blockCommand)\n .addCommand(pauseCommand)\n .addCommand(resumeCommand)\n .addCommand(clearCommand);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAsBA,SAAS,UAAU,OAAsB;AACvC,UAAQ,IAAI,KAAK,UAAU,KAAK,CAAC;AACnC;AAEA,IAAM,gBAAgB,IAAI,QAAQ,EAC/B,KAAK,QAAQ,EACb;AAAA,EACC;AACF,EACC;AAAA,EACC;AAAA,EACA;AACF,EACC;AAAA,EACC,iBAAiB,OAAO,YAA2B;AACjD,cAAU,MAAM,WAAW,EAAE,WAAW,QAAQ,UAAU,CAAC,CAAC;AAAA,EAC9D,CAAC;AACH;AAEF,IAAM,cAAc,IAAI,QAAQ,EAC7B,KAAK,MAAM,EACX,YAAY,wCAAwC,EACpD,eAAe,sBAAsB,oBAAoB,EACzD;AAAA,EACC,iBAAiB,OAAO,YAAyB;AAC/C,cAAU,MAAM,SAAS,EAAE,WAAW,QAAQ,UAAU,CAAC,CAAC;AAAA,EAC5D,CAAC;AACH;AAEF,IAAM,aAAa,IAAI,QAAQ,EAC5B,KAAK,KAAK,EACV,YAAY,6BAA6B,EACzC;AAAA,EACC,iBAAiB,YAAY;AAC3B,cAAU,MAAM,QAAQ,CAAC;AAAA,EAC3B,CAAC;AACH;AAEF,IAAM,kBAAkB,IAAI,QAAQ,EACjC,KAAK,UAAU,EACf,YAAY,uCAAuC,EACnD;AAAA,EACC,iBAAiB,YAAY;AAC3B,cAAU,MAAM,aAAa,CAAC;AAAA,EAChC,CAAC;AACH;AAEF,IAAM,eAAe,IAAI,QAAQ,EAC9B,KAAK,OAAO,EACZ,YAAY,sCAAsC,EAClD;AAAA,EACC,iBAAiB,YAAY;AAC3B,cAAU,MAAM,UAAU,CAAC;AAAA,EAC7B,CAAC;AACH;AAEF,IAAM,eAAe,IAAI,QAAQ,EAC9B,KAAK,OAAO,EACZ,YAAY,+BAA+B,EAC3C;AAAA,EACC,iBAAiB,YAAY;AAC3B,cAAU,MAAM,UAAU,CAAC;AAAA,EAC7B,CAAC;AACH;AAEF,IAAM,gBAAgB,IAAI,QAAQ,EAC/B,KAAK,QAAQ,EACb,YAAY,iDAAiD,EAC7D;AAAA,EACC,iBAAiB,YAAY;AAC3B,cAAU,MAAM,WAAW,CAAC;AAAA,EAC9B,CAAC;AACH;AAEF,IAAM,eAAe,IAAI,QAAQ,EAC9B,KAAK,OAAO,EACZ,YAAY,+BAA+B,EAC3C;AAAA,EACC,iBAAiB,YAAY;AAC3B,cAAU,MAAM,UAAU,CAAC;AAAA,EAC7B,CAAC;AACH;AAEK,IAAM,kBAAkB,IAAI,QAAQ,EACxC,KAAK,MAAM,EACX,YAAY,gCAAgC,EAC5C,WAAW,aAAa,EACxB,WAAW,WAAW,EACtB,WAAW,UAAU,EACrB,WAAW,eAAe,EAC1B,WAAW,YAAY,EACvB,WAAW,YAAY,EACvB,WAAW,aAAa,EACxB,WAAW,YAAY;","names":[]}
1
+ {"version":3,"sources":["../src/commands/zero/goal/index.ts"],"sourcesContent":["import { Command } from \"commander\";\n\nimport {\n blockGoal,\n clearGoal,\n completeGoal,\n createGoal,\n editGoal,\n getGoal,\n pauseGoal,\n resumeGoal,\n} from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\ninterface CreateOptions {\n readonly objective: string;\n}\n\ninterface EditOptions {\n readonly objective: string;\n}\n\nfunction printJson(value: unknown): void {\n console.log(JSON.stringify(value));\n}\n\nconst createCommand = new Command()\n .name(\"create\")\n .description(\n \"Create a persistent goal for the current thread. Create a goal ONLY when the user explicitly asks for a persistent, autonomous, cross-turn task; do not infer a goal from an ordinary one-off request.\",\n )\n .requiredOption(\n \"--objective <text>\",\n \"Goal objective. Set a goal ONLY on an explicit user request for autonomous cross-turn work; never infer one from a one-off request.\",\n )\n .action(\n withErrorHandler(async (options: CreateOptions) => {\n printJson(await createGoal({ objective: options.objective }));\n }),\n );\n\nconst editCommand = new Command()\n .name(\"edit\")\n .description(\"Edit the current thread goal objective\")\n .requiredOption(\"--objective <text>\", \"New goal objective\")\n .action(\n withErrorHandler(async (options: EditOptions) => {\n printJson(await editGoal({ objective: options.objective }));\n }),\n );\n\nconst getCommand = new Command()\n .name(\"get\")\n .description(\"Get the current thread goal\")\n .action(\n withErrorHandler(async () => {\n printJson(await getGoal());\n }),\n );\n\nconst completeCommand = new Command()\n .name(\"complete\")\n .description(\"Mark the current thread goal complete\")\n .action(\n withErrorHandler(async () => {\n printJson(await completeGoal());\n }),\n );\n\nconst blockCommand = new Command()\n .name(\"block\")\n .description(\"Mark the current thread goal blocked\")\n .action(\n withErrorHandler(async () => {\n printJson(await blockGoal());\n }),\n );\n\nconst pauseCommand = new Command()\n .name(\"pause\")\n .description(\"Pause the current thread goal\")\n .action(\n withErrorHandler(async () => {\n printJson(await pauseGoal());\n }),\n );\n\nconst resumeCommand = new Command()\n .name(\"resume\")\n .description(\"Resume continuation for the current thread goal\")\n .action(\n withErrorHandler(async () => {\n printJson(await resumeGoal());\n }),\n );\n\nconst clearCommand = new Command()\n .name(\"clear\")\n .description(\"Clear the current thread goal\")\n .action(\n withErrorHandler(async () => {\n printJson(await clearGoal());\n }),\n );\n\nexport const zeroGoalCommand = new Command()\n .name(\"goal\")\n .description(\"Manage the current thread goal\")\n .addCommand(createCommand)\n .addCommand(editCommand)\n .addCommand(getCommand)\n .addCommand(completeCommand)\n .addCommand(blockCommand)\n .addCommand(pauseCommand)\n .addCommand(resumeCommand)\n .addCommand(clearCommand);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAsBA,SAAS,UAAU,OAAsB;AACvC,UAAQ,IAAI,KAAK,UAAU,KAAK,CAAC;AACnC;AAEA,IAAM,gBAAgB,IAAI,QAAQ,EAC/B,KAAK,QAAQ,EACb;AAAA,EACC;AACF,EACC;AAAA,EACC;AAAA,EACA;AACF,EACC;AAAA,EACC,iBAAiB,OAAO,YAA2B;AACjD,cAAU,MAAM,WAAW,EAAE,WAAW,QAAQ,UAAU,CAAC,CAAC;AAAA,EAC9D,CAAC;AACH;AAEF,IAAM,cAAc,IAAI,QAAQ,EAC7B,KAAK,MAAM,EACX,YAAY,wCAAwC,EACpD,eAAe,sBAAsB,oBAAoB,EACzD;AAAA,EACC,iBAAiB,OAAO,YAAyB;AAC/C,cAAU,MAAM,SAAS,EAAE,WAAW,QAAQ,UAAU,CAAC,CAAC;AAAA,EAC5D,CAAC;AACH;AAEF,IAAM,aAAa,IAAI,QAAQ,EAC5B,KAAK,KAAK,EACV,YAAY,6BAA6B,EACzC;AAAA,EACC,iBAAiB,YAAY;AAC3B,cAAU,MAAM,QAAQ,CAAC;AAAA,EAC3B,CAAC;AACH;AAEF,IAAM,kBAAkB,IAAI,QAAQ,EACjC,KAAK,UAAU,EACf,YAAY,uCAAuC,EACnD;AAAA,EACC,iBAAiB,YAAY;AAC3B,cAAU,MAAM,aAAa,CAAC;AAAA,EAChC,CAAC;AACH;AAEF,IAAM,eAAe,IAAI,QAAQ,EAC9B,KAAK,OAAO,EACZ,YAAY,sCAAsC,EAClD;AAAA,EACC,iBAAiB,YAAY;AAC3B,cAAU,MAAM,UAAU,CAAC;AAAA,EAC7B,CAAC;AACH;AAEF,IAAM,eAAe,IAAI,QAAQ,EAC9B,KAAK,OAAO,EACZ,YAAY,+BAA+B,EAC3C;AAAA,EACC,iBAAiB,YAAY;AAC3B,cAAU,MAAM,UAAU,CAAC;AAAA,EAC7B,CAAC;AACH;AAEF,IAAM,gBAAgB,IAAI,QAAQ,EAC/B,KAAK,QAAQ,EACb,YAAY,iDAAiD,EAC7D;AAAA,EACC,iBAAiB,YAAY;AAC3B,cAAU,MAAM,WAAW,CAAC;AAAA,EAC9B,CAAC;AACH;AAEF,IAAM,eAAe,IAAI,QAAQ,EAC9B,KAAK,OAAO,EACZ,YAAY,+BAA+B,EAC3C;AAAA,EACC,iBAAiB,YAAY;AAC3B,cAAU,MAAM,UAAU,CAAC;AAAA,EAC7B,CAAC;AACH;AAEK,IAAM,kBAAkB,IAAI,QAAQ,EACxC,KAAK,MAAM,EACX,YAAY,gCAAgC,EAC5C,WAAW,aAAa,EACxB,WAAW,WAAW,EACtB,WAAW,UAAU,EACrB,WAAW,eAAe,EAC1B,WAAW,YAAY,EACvB,WAAW,YAAY,EACvB,WAAW,aAAa,EACxB,WAAW,YAAY;","names":[]}
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __createRequire } from "node:module";
3
+ const require = __createRequire(import.meta.url);
4
+ import {
5
+ init_esm_shims
6
+ } from "./chunk-DIRAZ3YX.js";
7
+
8
+ // ../../packages/connectors/src/firewall-metadata/routing-details/google-contacts.generated.ts
9
+ init_esm_shims();
10
+ var firewallRoutingMetadataJson = '{\n "type": "google-contacts",\n "label": "Google Contacts",\n "apis": [\n {\n "base": "https://people.googleapis.com",\n "environmentNames": [\n "GOOGLE_CONTACTS_TOKEN"\n ],\n "routes": [\n {\n "permissionName": "contact-groups.create",\n "rule": "POST /v1/contactGroups"\n },\n {\n "permissionName": "contact-groups.delete",\n "rule": "DELETE /v1/contactGroups/{contactGroupsId}"\n },\n {\n "permissionName": "contact-groups.read",\n "rule": "GET /v1/contactGroups"\n },\n {\n "permissionName": "contact-groups.read",\n "rule": "GET /v1/contactGroups/{contactGroupsId}"\n },\n {\n "permissionName": "contact-groups.read",\n "rule": "GET /v1/contactGroups:batchGet"\n },\n {\n "permissionName": "contact-groups.update",\n "rule": "PUT /v1/contactGroups/{contactGroupsId}"\n },\n {\n "permissionName": "contact-groups.update",\n "rule": "POST /v1/contactGroups/{contactGroupsId}/members:modify"\n },\n {\n "permissionName": "contact-photos.write",\n "rule": "DELETE /v1/people/{peopleId}:deleteContactPhoto"\n },\n {\n "permissionName": "contact-photos.write",\n "rule": "PATCH /v1/people/{peopleId}:updateContactPhoto"\n },\n {\n "permissionName": "contacts.create",\n "rule": "POST /v1/people:batchCreateContacts"\n },\n {\n "permissionName": "contacts.create",\n "rule": "POST /v1/people:createContact"\n },\n {\n "permissionName": "contacts.delete",\n "rule": "DELETE /v1/people/{peopleId}:deleteContact"\n },\n {\n "permissionName": "contacts.delete",\n "rule": "POST /v1/people:batchDeleteContacts"\n },\n {\n "permissionName": "contacts.read",\n "rule": "GET /v1/people/{peopleId}"\n },\n {\n "permissionName": "contacts.read",\n "rule": "GET /v1/people/{peopleId}/connections"\n },\n {\n "permissionName": "contacts.read",\n "rule": "GET /v1/people:batchGet"\n },\n {\n "permissionName": "contacts.read",\n "rule": "GET /v1/people:searchContacts"\n },\n {\n "permissionName": "contacts.update",\n "rule": "PATCH /v1/people/{peopleId}:updateContact"\n },\n {\n "permissionName": "contacts.update",\n "rule": "POST /v1/people:batchUpdateContacts"\n },\n {\n "permissionName": "directory.read",\n "rule": "GET /v1/people:listDirectoryPeople"\n },\n {\n "permissionName": "directory.read",\n "rule": "GET /v1/people:searchDirectoryPeople"\n },\n {\n "permissionName": "other-contacts.copy",\n "rule": "POST /v1/otherContacts/{otherContactsId}:copyOtherContactToMyContactsGroup"\n },\n {\n "permissionName": "other-contacts.read",\n "rule": "GET /v1/otherContacts"\n },\n {\n "permissionName": "other-contacts.read",\n "rule": "GET /v1/otherContacts:search"\n }\n ]\n }\n ]\n}';
11
+ var firewallRoutingMetadataValue = JSON.parse(firewallRoutingMetadataJson);
12
+ var firewallRoutingMetadata = firewallRoutingMetadataValue;
13
+ export {
14
+ firewallRoutingMetadata
15
+ };
16
+ //# sourceMappingURL=google-contacts.generated-FL6Z7MTD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../packages/connectors/src/firewall-metadata/routing-details/google-contacts.generated.ts"],"sourcesContent":["// Auto-generated by @vm0/firewalls-generator.\n// Regenerate: cd turbo && pnpm -F @vm0/firewalls-generator generate\n//\n// DO NOT EDIT THIS FILE MANUALLY.\nimport type { FirewallRoutingMetadata } from \"../types\";\n\nconst firewallRoutingMetadataJson = \"{\\n \\\"type\\\": \\\"google-contacts\\\",\\n \\\"label\\\": \\\"Google Contacts\\\",\\n \\\"apis\\\": [\\n {\\n \\\"base\\\": \\\"https://people.googleapis.com\\\",\\n \\\"environmentNames\\\": [\\n \\\"GOOGLE_CONTACTS_TOKEN\\\"\\n ],\\n \\\"routes\\\": [\\n {\\n \\\"permissionName\\\": \\\"contact-groups.create\\\",\\n \\\"rule\\\": \\\"POST /v1/contactGroups\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contact-groups.delete\\\",\\n \\\"rule\\\": \\\"DELETE /v1/contactGroups/{contactGroupsId}\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contact-groups.read\\\",\\n \\\"rule\\\": \\\"GET /v1/contactGroups\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contact-groups.read\\\",\\n \\\"rule\\\": \\\"GET /v1/contactGroups/{contactGroupsId}\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contact-groups.read\\\",\\n \\\"rule\\\": \\\"GET /v1/contactGroups:batchGet\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contact-groups.update\\\",\\n \\\"rule\\\": \\\"PUT /v1/contactGroups/{contactGroupsId}\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contact-groups.update\\\",\\n \\\"rule\\\": \\\"POST /v1/contactGroups/{contactGroupsId}/members:modify\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contact-photos.write\\\",\\n \\\"rule\\\": \\\"DELETE /v1/people/{peopleId}:deleteContactPhoto\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contact-photos.write\\\",\\n \\\"rule\\\": \\\"PATCH /v1/people/{peopleId}:updateContactPhoto\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contacts.create\\\",\\n \\\"rule\\\": \\\"POST /v1/people:batchCreateContacts\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contacts.create\\\",\\n \\\"rule\\\": \\\"POST /v1/people:createContact\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contacts.delete\\\",\\n \\\"rule\\\": \\\"DELETE /v1/people/{peopleId}:deleteContact\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contacts.delete\\\",\\n \\\"rule\\\": \\\"POST /v1/people:batchDeleteContacts\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contacts.read\\\",\\n \\\"rule\\\": \\\"GET /v1/people/{peopleId}\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contacts.read\\\",\\n \\\"rule\\\": \\\"GET /v1/people/{peopleId}/connections\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contacts.read\\\",\\n \\\"rule\\\": \\\"GET /v1/people:batchGet\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contacts.read\\\",\\n \\\"rule\\\": \\\"GET /v1/people:searchContacts\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contacts.update\\\",\\n \\\"rule\\\": \\\"PATCH /v1/people/{peopleId}:updateContact\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"contacts.update\\\",\\n \\\"rule\\\": \\\"POST /v1/people:batchUpdateContacts\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"directory.read\\\",\\n \\\"rule\\\": \\\"GET /v1/people:listDirectoryPeople\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"directory.read\\\",\\n \\\"rule\\\": \\\"GET /v1/people:searchDirectoryPeople\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"other-contacts.copy\\\",\\n \\\"rule\\\": \\\"POST /v1/otherContacts/{otherContactsId}:copyOtherContactToMyContactsGroup\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"other-contacts.read\\\",\\n \\\"rule\\\": \\\"GET /v1/otherContacts\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"other-contacts.read\\\",\\n \\\"rule\\\": \\\"GET /v1/otherContacts:search\\\"\\n }\\n ]\\n }\\n ]\\n}\";\nconst firewallRoutingMetadataValue: unknown = JSON.parse(firewallRoutingMetadataJson);\n\nexport const firewallRoutingMetadata = firewallRoutingMetadataValue as FirewallRoutingMetadata;\n"],"mappings":";;;;;;;;AAAA;AAMA,IAAM,8BAA8B;AACpC,IAAM,+BAAwC,KAAK,MAAM,2BAA2B;AAE7E,IAAM,0BAA0B;","names":[]}
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __createRequire } from "node:module";
3
+ const require = __createRequire(import.meta.url);
4
+ import {
5
+ init_esm_shims
6
+ } from "./chunk-DIRAZ3YX.js";
7
+
8
+ // ../../packages/connectors/src/firewall-metadata/permission-details/google-contacts.generated.ts
9
+ init_esm_shims();
10
+ var firewallPermissionMetadataJson = '{\n "type": "google-contacts",\n "label": "Google Contacts",\n "permissionCount": 12,\n "permissions": [\n {\n "name": "contact-groups.create",\n "description": "Create Google contact groups."\n },\n {\n "name": "contact-groups.delete",\n "description": "Delete Google contact groups."\n },\n {\n "name": "contact-groups.read",\n "description": "Read Google contact groups."\n },\n {\n "name": "contact-groups.update",\n "description": "Update Google contact groups and their memberships."\n },\n {\n "name": "contact-photos.write",\n "description": "Update or delete Google contact photos."\n },\n {\n "name": "contacts.create",\n "description": "Create Google contacts individually or in batches."\n },\n {\n "name": "contacts.delete",\n "description": "Delete Google contacts individually or in batches."\n },\n {\n "name": "contacts.read",\n "description": "Read and search Google contacts."\n },\n {\n "name": "contacts.update",\n "description": "Update Google contacts individually or in batches."\n },\n {\n "name": "directory.read",\n "description": "List and search Google Workspace directory people."\n },\n {\n "name": "other-contacts.copy",\n "description": "Copy an other contact into My Contacts."\n },\n {\n "name": "other-contacts.read",\n "description": "Read and search Google other contacts."\n }\n ],\n "categories": {\n "categories": {\n "contact-groups.create": "Contact Groups",\n "contact-groups.delete": "Contact Groups",\n "contact-groups.read": "Contact Groups",\n "contact-groups.update": "Contact Groups",\n "contact-photos.write": "Contacts",\n "contacts.create": "Contacts",\n "contacts.delete": "Contacts",\n "contacts.read": "Contacts",\n "contacts.update": "Contacts",\n "directory.read": "Directory",\n "other-contacts.copy": "Other Contacts",\n "other-contacts.read": "Other Contacts"\n },\n "displayOrder": [\n "Contacts",\n "Contact Groups",\n "Other Contacts",\n "Directory"\n ]\n },\n "defaultPolicy": {\n "permissionDefault": "deny",\n "permissionOverrides": {\n "allow": [\n "contact-groups.read",\n "contacts.read"\n ]\n },\n "unknownPolicy": "deny"\n }\n}';
11
+ var firewallPermissionMetadataValue = JSON.parse(firewallPermissionMetadataJson);
12
+ var firewallPermissionMetadata = firewallPermissionMetadataValue;
13
+ export {
14
+ firewallPermissionMetadata
15
+ };
16
+ //# sourceMappingURL=google-contacts.generated-Q67YBTPW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../packages/connectors/src/firewall-metadata/permission-details/google-contacts.generated.ts"],"sourcesContent":["// Auto-generated by @vm0/firewalls-generator.\n// Regenerate: cd turbo && pnpm -F @vm0/firewalls-generator generate\n//\n// DO NOT EDIT THIS FILE MANUALLY.\nimport type { FirewallPermissionDetailMetadata } from \"../types\";\n\nconst firewallPermissionMetadataJson = \"{\\n \\\"type\\\": \\\"google-contacts\\\",\\n \\\"label\\\": \\\"Google Contacts\\\",\\n \\\"permissionCount\\\": 12,\\n \\\"permissions\\\": [\\n {\\n \\\"name\\\": \\\"contact-groups.create\\\",\\n \\\"description\\\": \\\"Create Google contact groups.\\\"\\n },\\n {\\n \\\"name\\\": \\\"contact-groups.delete\\\",\\n \\\"description\\\": \\\"Delete Google contact groups.\\\"\\n },\\n {\\n \\\"name\\\": \\\"contact-groups.read\\\",\\n \\\"description\\\": \\\"Read Google contact groups.\\\"\\n },\\n {\\n \\\"name\\\": \\\"contact-groups.update\\\",\\n \\\"description\\\": \\\"Update Google contact groups and their memberships.\\\"\\n },\\n {\\n \\\"name\\\": \\\"contact-photos.write\\\",\\n \\\"description\\\": \\\"Update or delete Google contact photos.\\\"\\n },\\n {\\n \\\"name\\\": \\\"contacts.create\\\",\\n \\\"description\\\": \\\"Create Google contacts individually or in batches.\\\"\\n },\\n {\\n \\\"name\\\": \\\"contacts.delete\\\",\\n \\\"description\\\": \\\"Delete Google contacts individually or in batches.\\\"\\n },\\n {\\n \\\"name\\\": \\\"contacts.read\\\",\\n \\\"description\\\": \\\"Read and search Google contacts.\\\"\\n },\\n {\\n \\\"name\\\": \\\"contacts.update\\\",\\n \\\"description\\\": \\\"Update Google contacts individually or in batches.\\\"\\n },\\n {\\n \\\"name\\\": \\\"directory.read\\\",\\n \\\"description\\\": \\\"List and search Google Workspace directory people.\\\"\\n },\\n {\\n \\\"name\\\": \\\"other-contacts.copy\\\",\\n \\\"description\\\": \\\"Copy an other contact into My Contacts.\\\"\\n },\\n {\\n \\\"name\\\": \\\"other-contacts.read\\\",\\n \\\"description\\\": \\\"Read and search Google other contacts.\\\"\\n }\\n ],\\n \\\"categories\\\": {\\n \\\"categories\\\": {\\n \\\"contact-groups.create\\\": \\\"Contact Groups\\\",\\n \\\"contact-groups.delete\\\": \\\"Contact Groups\\\",\\n \\\"contact-groups.read\\\": \\\"Contact Groups\\\",\\n \\\"contact-groups.update\\\": \\\"Contact Groups\\\",\\n \\\"contact-photos.write\\\": \\\"Contacts\\\",\\n \\\"contacts.create\\\": \\\"Contacts\\\",\\n \\\"contacts.delete\\\": \\\"Contacts\\\",\\n \\\"contacts.read\\\": \\\"Contacts\\\",\\n \\\"contacts.update\\\": \\\"Contacts\\\",\\n \\\"directory.read\\\": \\\"Directory\\\",\\n \\\"other-contacts.copy\\\": \\\"Other Contacts\\\",\\n \\\"other-contacts.read\\\": \\\"Other Contacts\\\"\\n },\\n \\\"displayOrder\\\": [\\n \\\"Contacts\\\",\\n \\\"Contact Groups\\\",\\n \\\"Other Contacts\\\",\\n \\\"Directory\\\"\\n ]\\n },\\n \\\"defaultPolicy\\\": {\\n \\\"permissionDefault\\\": \\\"deny\\\",\\n \\\"permissionOverrides\\\": {\\n \\\"allow\\\": [\\n \\\"contact-groups.read\\\",\\n \\\"contacts.read\\\"\\n ]\\n },\\n \\\"unknownPolicy\\\": \\\"deny\\\"\\n }\\n}\";\nconst firewallPermissionMetadataValue: unknown = JSON.parse(firewallPermissionMetadataJson);\n\nexport const firewallPermissionMetadata = firewallPermissionMetadataValue as FirewallPermissionDetailMetadata;\n"],"mappings":";;;;;;;;AAAA;AAMA,IAAM,iCAAiC;AACvC,IAAM,kCAA2C,KAAK,MAAM,8BAA8B;AAEnF,IAAM,6BAA6B;","names":[]}
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __createRequire } from "node:module";
3
+ const require = __createRequire(import.meta.url);
4
+ import {
5
+ init_esm_shims
6
+ } from "./chunk-DIRAZ3YX.js";
7
+
8
+ // ../../packages/connectors/src/firewall-metadata/routing-details/google-forms.generated.ts
9
+ init_esm_shims();
10
+ var firewallRoutingMetadataJson = '{\n "type": "google-forms",\n "label": "Google Forms",\n "apis": [\n {\n "base": "https://forms.googleapis.com",\n "environmentNames": [\n "GOOGLE_FORMS_TOKEN"\n ],\n "routes": [\n {\n "permissionName": "forms.create",\n "rule": "POST /v1/forms"\n },\n {\n "permissionName": "forms.publish",\n "rule": "POST /v1/forms/{formId}:setPublishSettings"\n },\n {\n "permissionName": "forms.read",\n "rule": "GET /v1/forms/{formId}"\n },\n {\n "permissionName": "forms.write",\n "rule": "POST /v1/forms/{formId}:batchUpdate"\n },\n {\n "permissionName": "responses.read",\n "rule": "GET /v1/forms/{formId}/responses"\n },\n {\n "permissionName": "responses.read",\n "rule": "GET /v1/forms/{formId}/responses/{responseId}"\n },\n {\n "permissionName": "watches.create",\n "rule": "POST /v1/forms/{formId}/watches"\n },\n {\n "permissionName": "watches.delete",\n "rule": "DELETE /v1/forms/{formId}/watches/{watchId}"\n },\n {\n "permissionName": "watches.read",\n "rule": "GET /v1/forms/{formId}/watches"\n },\n {\n "permissionName": "watches.renew",\n "rule": "POST /v1/forms/{formId}/watches/{watchId}:renew"\n }\n ]\n }\n ]\n}';
11
+ var firewallRoutingMetadataValue = JSON.parse(firewallRoutingMetadataJson);
12
+ var firewallRoutingMetadata = firewallRoutingMetadataValue;
13
+ export {
14
+ firewallRoutingMetadata
15
+ };
16
+ //# sourceMappingURL=google-forms.generated-AOKO24AB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../packages/connectors/src/firewall-metadata/routing-details/google-forms.generated.ts"],"sourcesContent":["// Auto-generated by @vm0/firewalls-generator.\n// Regenerate: cd turbo && pnpm -F @vm0/firewalls-generator generate\n//\n// DO NOT EDIT THIS FILE MANUALLY.\nimport type { FirewallRoutingMetadata } from \"../types\";\n\nconst firewallRoutingMetadataJson = \"{\\n \\\"type\\\": \\\"google-forms\\\",\\n \\\"label\\\": \\\"Google Forms\\\",\\n \\\"apis\\\": [\\n {\\n \\\"base\\\": \\\"https://forms.googleapis.com\\\",\\n \\\"environmentNames\\\": [\\n \\\"GOOGLE_FORMS_TOKEN\\\"\\n ],\\n \\\"routes\\\": [\\n {\\n \\\"permissionName\\\": \\\"forms.create\\\",\\n \\\"rule\\\": \\\"POST /v1/forms\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"forms.publish\\\",\\n \\\"rule\\\": \\\"POST /v1/forms/{formId}:setPublishSettings\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"forms.read\\\",\\n \\\"rule\\\": \\\"GET /v1/forms/{formId}\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"forms.write\\\",\\n \\\"rule\\\": \\\"POST /v1/forms/{formId}:batchUpdate\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"responses.read\\\",\\n \\\"rule\\\": \\\"GET /v1/forms/{formId}/responses\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"responses.read\\\",\\n \\\"rule\\\": \\\"GET /v1/forms/{formId}/responses/{responseId}\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"watches.create\\\",\\n \\\"rule\\\": \\\"POST /v1/forms/{formId}/watches\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"watches.delete\\\",\\n \\\"rule\\\": \\\"DELETE /v1/forms/{formId}/watches/{watchId}\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"watches.read\\\",\\n \\\"rule\\\": \\\"GET /v1/forms/{formId}/watches\\\"\\n },\\n {\\n \\\"permissionName\\\": \\\"watches.renew\\\",\\n \\\"rule\\\": \\\"POST /v1/forms/{formId}/watches/{watchId}:renew\\\"\\n }\\n ]\\n }\\n ]\\n}\";\nconst firewallRoutingMetadataValue: unknown = JSON.parse(firewallRoutingMetadataJson);\n\nexport const firewallRoutingMetadata = firewallRoutingMetadataValue as FirewallRoutingMetadata;\n"],"mappings":";;;;;;;;AAAA;AAMA,IAAM,8BAA8B;AACpC,IAAM,+BAAwC,KAAK,MAAM,2BAA2B;AAE7E,IAAM,0BAA0B;","names":[]}
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __createRequire } from "node:module";
3
+ const require = __createRequire(import.meta.url);
4
+ import {
5
+ init_esm_shims
6
+ } from "./chunk-DIRAZ3YX.js";
7
+
8
+ // ../../packages/connectors/src/firewall-metadata/permission-details/google-forms.generated.ts
9
+ init_esm_shims();
10
+ var firewallPermissionMetadataJson = '{\n "type": "google-forms",\n "label": "Google Forms",\n "permissionCount": 9,\n "permissions": [\n {\n "name": "forms.create",\n "description": "Create Google Forms."\n },\n {\n "name": "forms.publish",\n "description": "Update Google Forms publish settings."\n },\n {\n "name": "forms.read",\n "description": "Read Google Forms content and metadata."\n },\n {\n "name": "forms.write",\n "description": "Apply batch updates to Google Forms."\n },\n {\n "name": "responses.read",\n "description": "List and read Google Forms responses."\n },\n {\n "name": "watches.create",\n "description": "Create Google Forms event watches."\n },\n {\n "name": "watches.delete",\n "description": "Delete Google Forms event watches."\n },\n {\n "name": "watches.read",\n "description": "List Google Forms event watches."\n },\n {\n "name": "watches.renew",\n "description": "Renew Google Forms event watches."\n }\n ],\n "categories": {\n "categories": {\n "forms.create": "Forms",\n "forms.publish": "Forms",\n "forms.read": "Forms",\n "forms.write": "Forms",\n "responses.read": "Responses",\n "watches.create": "Watches",\n "watches.delete": "Watches",\n "watches.read": "Watches",\n "watches.renew": "Watches"\n },\n "displayOrder": [\n "Forms",\n "Responses",\n "Watches"\n ]\n },\n "defaultPolicy": {\n "permissionDefault": "deny",\n "permissionOverrides": {\n "allow": [\n "forms.read",\n "responses.read",\n "watches.read"\n ]\n },\n "unknownPolicy": "deny"\n }\n}';
11
+ var firewallPermissionMetadataValue = JSON.parse(firewallPermissionMetadataJson);
12
+ var firewallPermissionMetadata = firewallPermissionMetadataValue;
13
+ export {
14
+ firewallPermissionMetadata
15
+ };
16
+ //# sourceMappingURL=google-forms.generated-KDCHIV43.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../packages/connectors/src/firewall-metadata/permission-details/google-forms.generated.ts"],"sourcesContent":["// Auto-generated by @vm0/firewalls-generator.\n// Regenerate: cd turbo && pnpm -F @vm0/firewalls-generator generate\n//\n// DO NOT EDIT THIS FILE MANUALLY.\nimport type { FirewallPermissionDetailMetadata } from \"../types\";\n\nconst firewallPermissionMetadataJson = \"{\\n \\\"type\\\": \\\"google-forms\\\",\\n \\\"label\\\": \\\"Google Forms\\\",\\n \\\"permissionCount\\\": 9,\\n \\\"permissions\\\": [\\n {\\n \\\"name\\\": \\\"forms.create\\\",\\n \\\"description\\\": \\\"Create Google Forms.\\\"\\n },\\n {\\n \\\"name\\\": \\\"forms.publish\\\",\\n \\\"description\\\": \\\"Update Google Forms publish settings.\\\"\\n },\\n {\\n \\\"name\\\": \\\"forms.read\\\",\\n \\\"description\\\": \\\"Read Google Forms content and metadata.\\\"\\n },\\n {\\n \\\"name\\\": \\\"forms.write\\\",\\n \\\"description\\\": \\\"Apply batch updates to Google Forms.\\\"\\n },\\n {\\n \\\"name\\\": \\\"responses.read\\\",\\n \\\"description\\\": \\\"List and read Google Forms responses.\\\"\\n },\\n {\\n \\\"name\\\": \\\"watches.create\\\",\\n \\\"description\\\": \\\"Create Google Forms event watches.\\\"\\n },\\n {\\n \\\"name\\\": \\\"watches.delete\\\",\\n \\\"description\\\": \\\"Delete Google Forms event watches.\\\"\\n },\\n {\\n \\\"name\\\": \\\"watches.read\\\",\\n \\\"description\\\": \\\"List Google Forms event watches.\\\"\\n },\\n {\\n \\\"name\\\": \\\"watches.renew\\\",\\n \\\"description\\\": \\\"Renew Google Forms event watches.\\\"\\n }\\n ],\\n \\\"categories\\\": {\\n \\\"categories\\\": {\\n \\\"forms.create\\\": \\\"Forms\\\",\\n \\\"forms.publish\\\": \\\"Forms\\\",\\n \\\"forms.read\\\": \\\"Forms\\\",\\n \\\"forms.write\\\": \\\"Forms\\\",\\n \\\"responses.read\\\": \\\"Responses\\\",\\n \\\"watches.create\\\": \\\"Watches\\\",\\n \\\"watches.delete\\\": \\\"Watches\\\",\\n \\\"watches.read\\\": \\\"Watches\\\",\\n \\\"watches.renew\\\": \\\"Watches\\\"\\n },\\n \\\"displayOrder\\\": [\\n \\\"Forms\\\",\\n \\\"Responses\\\",\\n \\\"Watches\\\"\\n ]\\n },\\n \\\"defaultPolicy\\\": {\\n \\\"permissionDefault\\\": \\\"deny\\\",\\n \\\"permissionOverrides\\\": {\\n \\\"allow\\\": [\\n \\\"forms.read\\\",\\n \\\"responses.read\\\",\\n \\\"watches.read\\\"\\n ]\\n },\\n \\\"unknownPolicy\\\": \\\"deny\\\"\\n }\\n}\";\nconst firewallPermissionMetadataValue: unknown = JSON.parse(firewallPermissionMetadataJson);\n\nexport const firewallPermissionMetadata = firewallPermissionMetadataValue as FirewallPermissionDetailMetadata;\n"],"mappings":";;;;;;;;AAAA;AAMA,IAAM,iCAAiC;AACvC,IAAM,kCAA2C,KAAK,MAAM,8BAA8B;AAEnF,IAAM,6BAA6B;","names":[]}
@@ -11,14 +11,12 @@ import {
11
11
  getHostedSiteFiles,
12
12
  hostedArtifactKindSchema,
13
13
  prepareHostedSite
14
- } from "./chunk-XX3HVOWG.js";
14
+ } from "./chunk-GIACTMOF.js";
15
15
  import "./chunk-LTDQISD7.js";
16
16
  import {
17
+ source_default,
17
18
  withErrorHandler
18
- } from "./chunk-22VWTDX6.js";
19
- import {
20
- source_default
21
- } from "./chunk-JUTUEPIR.js";
19
+ } from "./chunk-VC7E6IA7.js";
22
20
  import "./chunk-LRHXR7JT.js";
23
21
  import {
24
22
  Command
@@ -550,4 +548,4 @@ Notes:
550
548
  export {
551
549
  zeroHostCommand
552
550
  };
553
- //# sourceMappingURL=host-YMKJGV6R.js.map
551
+ //# sourceMappingURL=host-EVFNV5BX.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/zero/host/index.ts","../src/lib/host/publish-static-site.ts","../src/lib/host/static-site.ts","../src/commands/zero/host/clone.ts","../src/lib/host/clone-hosted-site.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport {\n hostedArtifactKindSchema,\n type HostedArtifactKind,\n} from \"@vm0/api-contracts/contracts/zero-host\";\nimport { withErrorHandler } from \"../../../lib/command\";\nimport { publishStaticSite } from \"../../../lib/host/publish-static-site\";\nimport { cloneHostedSiteCommand } from \"./clone\";\n\ninterface HostOptions {\n readonly site?: string;\n readonly slugSuffix?: string;\n readonly artifactKind?: HostedArtifactKind;\n readonly spa?: boolean;\n readonly json?: boolean;\n}\n\nfunction parseArtifactKind(value: string): HostedArtifactKind {\n return hostedArtifactKindSchema.parse(value);\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nexport const zeroHostCommand = new Command()\n .name(\"host\")\n .description(\"Publish static sites and clone owned hosted site files\")\n .argument(\"<dir>\", \"Static build directory, for example ./dist\")\n .option(\"--site <slug>\", \"Public site slug, e.g. my-product-demo\")\n .option(\"--slug-suffix <suffix>\", \"Reuse a generated site URL suffix\")\n .option(\n \"--artifact-kind <kind>\",\n \"Artifact kind to record for this hosted deployment\",\n parseArtifactKind,\n )\n .option(\"--spa\", \"Serve unknown HTML navigation paths from index.html\")\n .option(\"--json\", \"Output only the final result as JSON\")\n .addCommand(cloneHostedSiteCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n Publish a Vite build: zero host ./dist --site my-product-demo --spa\n Redeploy a URL: zero host ./dist --site my-product-demo --slug-suffix a1b2c3d4 --spa\n Clone a hosted site: zero host clone my-product-demo-a1b2c3d4-release-01 ./site\n Machine readable: zero host ./dist --site my-product-demo --spa --json\n\nNotes:\n - Authenticates via ZERO_TOKEN (publish requires host:write; clone requires host:read)\n - Reusing both --site and --slug-suffix keeps the same URL\n - The directory must include index.html\n - Local HTML/CSS asset references must point at files inside the directory`,\n )\n .action(\n withErrorHandler(async (dir: string, options: HostOptions) => {\n if (!options.site) {\n throw new Error(\"--site is required when publishing a hosted site\");\n }\n const result = await publishStaticSite({\n dir,\n site: options.site,\n slugSuffix: options.slugSuffix,\n artifactKind: options.artifactKind,\n spaFallback: Boolean(options.spa),\n onProgress: options.json\n ? undefined\n : (progress) => {\n if (progress.phase === \"preparing\") {\n console.log(\n chalk.dim(`Preparing ${progress.fileCount} files...`),\n );\n return;\n }\n console.log(chalk.dim(`Uploading ${progress.path}`));\n },\n });\n\n if (options.json) {\n console.log(JSON.stringify(result));\n return;\n }\n\n console.log(chalk.green(\"✓ Hosted site ready\"));\n console.log(chalk.dim(` Site: ${result.publicSlug}`));\n console.log(chalk.dim(` Deployment: ${result.deploymentId}`));\n console.log(chalk.dim(` Files: ${result.fileCount.toLocaleString()}`));\n console.log(chalk.dim(` Size: ${formatBytes(result.size)}`));\n console.log(` URL: ${result.url}`);\n }),\n );\n","import type { HostedArtifactKind } from \"@vm0/api-contracts/contracts/zero-host\";\nimport { completeHostedSite, prepareHostedSite } from \"../api\";\nimport { readStaticSiteFile, scanStaticSite } from \"./static-site\";\n\ninterface PublishStaticSiteProgress {\n readonly phase: \"preparing\" | \"uploading\";\n readonly fileCount?: number;\n readonly path?: string;\n}\n\ninterface PublishStaticSiteResult {\n readonly siteId: string;\n readonly deploymentId: string;\n readonly publicSlug: string;\n readonly url: string;\n readonly fileCount: number;\n readonly size: number;\n}\n\ninterface PublishStaticSiteOptions {\n readonly dir: string;\n readonly site: string;\n readonly slugSuffix?: string;\n readonly artifactKind?: HostedArtifactKind;\n readonly spaFallback?: boolean;\n readonly onProgress?: (progress: PublishStaticSiteProgress) => void;\n}\n\nexport async function publishStaticSite(\n options: PublishStaticSiteOptions,\n): Promise<PublishStaticSiteResult> {\n const artifactKind = options.artifactKind ?? \"hosted-site\";\n const scan = await scanStaticSite(\n options.dir,\n artifactKind === \"hosted-site\" ? { defaultRobots: \"disallow-all\" } : {},\n );\n const totalSize = scan.files.reduce((sum, file) => {\n return sum + file.size;\n }, 0);\n\n options.onProgress?.({\n phase: \"preparing\",\n fileCount: scan.files.length,\n });\n\n const prepared = await prepareHostedSite({\n site: options.site,\n ...(options.slugSuffix !== undefined && { slugSuffix: options.slugSuffix }),\n artifactKind,\n spaFallback: Boolean(options.spaFallback),\n files: scan.files.map((file) => {\n return {\n path: file.path,\n size: file.size,\n sha256: file.sha256,\n contentType: file.contentType,\n immutable: file.immutable,\n };\n }),\n });\n\n const uploadByPath = new Map(\n prepared.uploads.map((upload) => {\n return [upload.path, upload.uploadUrl];\n }),\n );\n\n for (const file of scan.files) {\n const uploadUrl = uploadByPath.get(file.path);\n if (!uploadUrl) {\n throw new Error(`Missing upload URL for ${file.path}`);\n }\n options.onProgress?.({ phase: \"uploading\", path: file.path });\n const bytes = await readStaticSiteFile(file);\n const response = await fetch(uploadUrl, {\n method: \"PUT\",\n headers: { \"Content-Type\": file.contentType },\n body: new Uint8Array(bytes),\n });\n if (!response.ok) {\n throw new Error(\n `Failed to upload ${file.path} (HTTP ${response.status})`,\n );\n }\n }\n\n const completed = await completeHostedSite(prepared.deploymentId);\n\n return {\n siteId: completed.siteId,\n deploymentId: completed.deploymentId,\n publicSlug: completed.publicSlug,\n url: completed.url,\n fileCount: scan.files.length,\n size: totalSize,\n };\n}\n","import { createHash } from \"node:crypto\";\nimport { readdir, readFile, stat } from \"node:fs/promises\";\nimport { extname, relative, resolve, sep, dirname, posix } from \"node:path\";\n\ninterface StaticSiteFile {\n readonly absolutePath?: string;\n readonly content?: Uint8Array;\n readonly path: string;\n readonly size: number;\n readonly sha256: string;\n readonly contentType: string;\n readonly immutable?: boolean;\n}\n\ninterface StaticSiteScanOptions {\n readonly defaultRobots?: \"disallow-all\";\n}\n\ninterface StaticSiteScanResult {\n readonly root: string;\n readonly files: readonly StaticSiteFile[];\n}\n\nexport const DEFAULT_HOSTED_SITE_ROBOTS_TXT = \"User-agent: *\\nDisallow: /\\n\";\n\nconst MIME_BY_EXTENSION: Record<string, string> = {\n \".html\": \"text/html; charset=utf-8\",\n \".htm\": \"text/html; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".js\": \"application/javascript; charset=utf-8\",\n \".mjs\": \"application/javascript; charset=utf-8\",\n \".json\": \"application/json; charset=utf-8\",\n \".map\": \"application/json; charset=utf-8\",\n \".txt\": \"text/plain; charset=utf-8\",\n \".xml\": \"application/xml; charset=utf-8\",\n \".svg\": \"image/svg+xml; charset=utf-8\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".avif\": \"image/avif\",\n \".ico\": \"image/x-icon\",\n \".wasm\": \"application/wasm\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".otf\": \"font/otf\",\n \".eot\": \"application/vnd.ms-fontobject\",\n \".mp4\": \"video/mp4\",\n \".webm\": \"video/webm\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n};\n\nconst HTML_REFERENCE_RE =\n /<(?:script|link|img|source|video|audio|embed|object)\\b[^>]*\\s(?:src|href|poster|data)=[\"']([^\"']+)[\"'][^>]*>/giu;\nconst SRCSET_RE = /\\s(?:srcset)=[\"']([^\"']+)[\"']/giu;\nconst CSS_URL_RE = /url\\(\\s*[\"']?([^\"')]+)[\"']?\\s*\\)/giu;\nconst CSS_IMPORT_RE = /@import\\s+(?:url\\()?[\"']([^\"']+)[\"']\\)?/giu;\n\nfunction inferContentType(path: string): string {\n return (\n MIME_BY_EXTENSION[extname(path).toLowerCase()] ?? \"application/octet-stream\"\n );\n}\n\nfunction looksImmutable(path: string): boolean {\n if (path.startsWith(\"/assets/\")) {\n return true;\n }\n return /(?:[-.])[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9]+$/u.test(path);\n}\n\nfunction toSitePath(root: string, absolutePath: string): string {\n const rel = relative(root, absolutePath).split(sep).join(\"/\");\n return `/${rel}`;\n}\n\nfunction isSafeSitePath(path: string): boolean {\n if (!path.startsWith(\"/\") || path.startsWith(\"//\")) {\n return false;\n }\n if (path.includes(\"\\\\\") || path.includes(\"\\0\")) {\n return false;\n }\n const segments = path.split(\"/\").filter(Boolean);\n return !segments.some((segment) => {\n return segment === \".\" || segment === \"..\";\n });\n}\n\nfunction isExternalReference(value: string): boolean {\n return /^(?:[a-z][a-z0-9+.-]*:|\\/\\/|#)/iu.test(value);\n}\n\n// References containing template interpolation are resolved at runtime, not on\n// disk. Covers JS template literals (`${...}`), mustache/Vue/Angular/Handlebars\n// (`{{...}}`), and EJS/ERB (`<%...%>`). These cannot be validated statically.\nfunction isDynamicReference(value: string): boolean {\n return /\\$\\{|\\{\\{|<%/u.test(value);\n}\n\nfunction stripQueryAndHash(value: string): string {\n const hashIndex = value.indexOf(\"#\");\n const withoutHash = hashIndex >= 0 ? value.slice(0, hashIndex) : value;\n const queryIndex = withoutHash.indexOf(\"?\");\n return queryIndex >= 0 ? withoutHash.slice(0, queryIndex) : withoutHash;\n}\n\nfunction normalizeReference(fromPath: string, raw: string): string | null {\n const trimmed = raw.trim();\n if (!trimmed || isExternalReference(trimmed) || isDynamicReference(trimmed)) {\n return null;\n }\n const stripped = stripQueryAndHash(trimmed);\n if (!stripped || stripped.endsWith(\"/\")) {\n return null;\n }\n const resolved = stripped.startsWith(\"/\")\n ? posix.normalize(stripped)\n : posix.normalize(posix.join(dirname(fromPath), stripped));\n const path = resolved.startsWith(\"/\") ? resolved : `/${resolved}`;\n if (!isSafeSitePath(path)) {\n throw new Error(`Invalid asset reference in ${fromPath}: ${raw}`);\n }\n return path;\n}\n\nfunction shouldRequireHtmlReference(path: string): boolean {\n return extname(path).length > 0 || path.startsWith(\"/assets/\");\n}\n\nfunction isHtmlExtension(ext: string): boolean {\n return ext === \".html\" || ext === \".htm\";\n}\n\nfunction shouldValidateReferences(ext: string): boolean {\n return isHtmlExtension(ext) || ext === \".css\";\n}\n\nfunction collectSrcsetReferences(value: string): string[] {\n return value\n .split(\",\")\n .map((entry) => {\n return entry.trim().split(/\\s+/u)[0] ?? \"\";\n })\n .filter(Boolean);\n}\n\nfunction collectHtmlReferences(text: string): string[] {\n const references: string[] = [];\n for (const match of text.matchAll(HTML_REFERENCE_RE)) {\n if (match[1]) references.push(match[1]);\n }\n for (const match of text.matchAll(SRCSET_RE)) {\n if (!match[1]) continue;\n references.push(...collectSrcsetReferences(match[1]));\n }\n return references;\n}\n\nfunction collectCssReferences(text: string): string[] {\n const references: string[] = [];\n for (const match of text.matchAll(CSS_URL_RE)) {\n if (match[1]) references.push(match[1]);\n }\n for (const match of text.matchAll(CSS_IMPORT_RE)) {\n if (match[1]) references.push(match[1]);\n }\n return references;\n}\n\nfunction collectReferences(ext: string, text: string): string[] {\n return isHtmlExtension(ext)\n ? collectHtmlReferences(text)\n : collectCssReferences(text);\n}\n\nasync function hashFile(path: string): Promise<string> {\n const bytes = await readFile(path);\n return createHash(\"sha256\").update(bytes).digest(\"hex\");\n}\n\nfunction textFile(path: string, content: string): StaticSiteFile {\n const bytes = new TextEncoder().encode(content);\n return {\n content: bytes,\n path,\n size: bytes.byteLength,\n sha256: createHash(\"sha256\").update(bytes).digest(\"hex\"),\n contentType: inferContentType(path),\n };\n}\n\nfunction ensureDefaultRobots(\n files: readonly StaticSiteFile[],\n options: StaticSiteScanOptions,\n): readonly StaticSiteFile[] {\n if (\n options.defaultRobots !== \"disallow-all\" ||\n files.some((file) => {\n return file.path === \"/robots.txt\";\n })\n ) {\n return files;\n }\n\n return [...files, textFile(\"/robots.txt\", DEFAULT_HOSTED_SITE_ROBOTS_TXT)];\n}\n\nasync function walk(\n root: string,\n dir: string,\n files: StaticSiteFile[],\n): Promise<void> {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = resolve(dir, entry.name);\n if (entry.isDirectory()) {\n await walk(root, fullPath, files);\n continue;\n }\n if (!entry.isFile()) {\n throw new Error(`Unsupported file type in hosted site: ${fullPath}`);\n }\n\n const fileStat = await stat(fullPath);\n const path = toSitePath(root, fullPath);\n if (!isSafeSitePath(path)) {\n throw new Error(`Invalid hosted-site path: ${path}`);\n }\n files.push({\n absolutePath: fullPath,\n path,\n size: fileStat.size,\n sha256: await hashFile(fullPath),\n contentType: inferContentType(path),\n immutable: looksImmutable(path) || undefined,\n });\n }\n}\n\nasync function assertReferencesExist(\n files: readonly StaticSiteFile[],\n): Promise<void> {\n const byPath = new Map(\n files.map((file) => {\n return [file.path, file];\n }),\n );\n\n for (const file of files) {\n const ext = extname(file.path).toLowerCase();\n if (!shouldValidateReferences(ext)) {\n continue;\n }\n if (!file.absolutePath) {\n throw new Error(`Hosted-site file has no source: ${file.path}`);\n }\n const text = await readFile(file.absolutePath, \"utf8\");\n const references = collectReferences(ext, text);\n\n for (const reference of references) {\n const normalized = normalizeReference(file.path, reference);\n if (!normalized) {\n continue;\n }\n if (isHtmlExtension(ext) && !shouldRequireHtmlReference(normalized)) {\n continue;\n }\n if (!byPath.has(normalized)) {\n throw new Error(\n `Missing asset referenced by ${file.path}: ${reference}`,\n );\n }\n }\n }\n}\n\nexport async function scanStaticSite(\n rootPath: string,\n options: StaticSiteScanOptions = {},\n): Promise<StaticSiteScanResult> {\n const root = resolve(rootPath);\n const rootStat = await stat(root);\n if (!rootStat.isDirectory()) {\n throw new Error(`Hosted site path must be a directory: ${rootPath}`);\n }\n\n const files: StaticSiteFile[] = [];\n await walk(root, root, files);\n\n if (\n !files.some((file) => {\n return file.path === \"/index.html\";\n })\n ) {\n throw new Error(\"Hosted site directory must include index.html\");\n }\n\n await assertReferencesExist(files);\n const publishFiles = [...ensureDefaultRobots(files, options)];\n\n return {\n root,\n files: publishFiles.sort((a, b) => {\n return a.path.localeCompare(b.path);\n }),\n };\n}\n\nexport async function readStaticSiteFile(\n file: StaticSiteFile,\n): Promise<Uint8Array> {\n if (file.content) {\n return file.content;\n }\n if (!file.absolutePath) {\n throw new Error(`Hosted-site file has no source: ${file.path}`);\n }\n const bytes = await readFile(file.absolutePath);\n return new Uint8Array(bytes);\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\n\nimport { withErrorHandler } from \"../../../lib/command\";\nimport {\n cloneHostedSite,\n publicSlugFromSite,\n} from \"../../../lib/host/clone-hosted-site\";\nimport { formatBytes } from \"../../../lib/utils/file-utils\";\n\ninterface CloneOptions {\n readonly json?: boolean;\n}\n\nfunction jsonOption(options: CloneOptions, command: Command): boolean {\n const parentOptions = command.parent?.opts<CloneOptions>();\n return Boolean(options.json || parentOptions?.json);\n}\n\nexport const cloneHostedSiteCommand = new Command()\n .name(\"clone\")\n .description(\"Clone an owned hosted site's active files to a local directory\")\n .argument(\"<site>\", \"Hosted site public slug or URL\")\n .argument(\"[destination]\", \"Destination directory (default: public slug)\")\n .option(\"--json\", \"Output only the final result as JSON\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Clone by public slug: zero host clone my-site-a1b2c3d4-release-01\n Clone by hosted URL: zero host clone https://my-site-a1b2c3d4-release-01.sites.example.com ./site\n Machine readable: zero host clone my-site-a1b2c3d4-release-01 --json\n\nNotes:\n - Authenticates via ZERO_TOKEN (requires host:read capability)\n - Only hosted sites owned by the active org can be cloned\n - Downloads files directly from R2 and verifies size/hash\n - The destination directory must be empty or not exist`,\n )\n .action(\n withErrorHandler(\n async (\n site: string,\n destination: string | undefined,\n options: CloneOptions,\n command: Command,\n ) => {\n const json = jsonOption(options, command);\n const targetDir = destination ?? publicSlugFromSite(site);\n const result = await cloneHostedSite({\n site,\n destination: targetDir,\n onProgress: json\n ? undefined\n : (progress) => {\n if (progress.phase === \"checking\") {\n console.log(chalk.dim(\"Checking hosted site...\"));\n return;\n }\n if (progress.phase === \"creating\") {\n console.log(\n chalk.dim(\n `Preparing ${progress.fileCount?.toLocaleString() ?? 0} files...`,\n ),\n );\n return;\n }\n console.log(chalk.dim(`Downloading ${progress.path}`));\n },\n });\n\n if (json) {\n console.log(JSON.stringify(result));\n return;\n }\n\n console.log(chalk.green(\"✓ Hosted site cloned\"));\n console.log(chalk.dim(` Site: ${result.publicSlug}`));\n console.log(chalk.dim(` Deployment: ${result.deploymentId}`));\n console.log(chalk.dim(` Files: ${result.fileCount.toLocaleString()}`));\n console.log(chalk.dim(` Size: ${formatBytes(result.size)}`));\n console.log(chalk.dim(` Location: ${result.destination}/`));\n console.log(` URL: ${result.url}`);\n },\n ),\n );\n","import { createHash } from \"node:crypto\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, relative, resolve, sep } from \"node:path\";\n\nimport type { HostedSiteFilesResponse } from \"@vm0/api-contracts/contracts/zero-host\";\nimport { getHostedSiteFiles } from \"../api\";\nimport { checkDirectoryStatus } from \"../utils/file-utils\";\n\ninterface CloneHostedSiteProgress {\n readonly phase: \"checking\" | \"creating\" | \"downloading\";\n readonly fileCount?: number;\n readonly path?: string;\n}\n\ninterface CloneHostedSiteResult {\n readonly siteId: string;\n readonly deploymentId: string;\n readonly publicSlug: string;\n readonly url: string;\n readonly destination: string;\n readonly fileCount: number;\n readonly size: number;\n}\n\ninterface CloneHostedSiteOptions {\n readonly site: string;\n readonly destination: string;\n readonly onProgress?: (progress: CloneHostedSiteProgress) => void;\n}\n\nexport function publicSlugFromSite(value: string): string {\n const trimmed = value.trim();\n if (URL.canParse(trimmed)) {\n const url = new URL(trimmed);\n return url.hostname.split(\".\")[0] ?? trimmed;\n }\n if (trimmed.includes(\".\")) {\n return trimmed.split(\".\")[0] ?? trimmed;\n }\n return trimmed;\n}\n\nfunction isInsideDirectory(parent: string, target: string): boolean {\n const relativePath = relative(parent, target);\n return (\n relativePath === \"\" ||\n (!relativePath.startsWith(`..${sep}`) &&\n relativePath !== \"..\" &&\n !isAbsolute(relativePath))\n );\n}\n\nfunction outputPathForHostedFile(\n destination: string,\n hostedPath: string,\n): string {\n if (\n !hostedPath.startsWith(\"/\") ||\n hostedPath.startsWith(\"//\") ||\n hostedPath.includes(\"\\\\\") ||\n hostedPath.includes(\"\\0\")\n ) {\n throw new Error(`Invalid hosted-site path: ${hostedPath}`);\n }\n\n const segments = hostedPath.split(\"/\").filter((segment) => {\n return segment.length > 0;\n });\n if (\n segments.length === 0 ||\n segments.some((segment) => {\n return segment === \".\" || segment === \"..\";\n })\n ) {\n throw new Error(`Invalid hosted-site path: ${hostedPath}`);\n }\n\n const destinationRoot = resolve(destination);\n const outputPath = resolve(destinationRoot, ...segments);\n if (!isInsideDirectory(destinationRoot, outputPath)) {\n throw new Error(`Invalid hosted-site path: ${hostedPath}`);\n }\n\n return outputPath;\n}\n\nfunction sha256(bytes: Buffer): string {\n return createHash(\"sha256\").update(bytes).digest(\"hex\");\n}\n\nasync function downloadHostedFile(\n file: HostedSiteFilesResponse[\"files\"][number],\n destination: string,\n): Promise<void> {\n const response = await fetch(file.downloadUrl);\n if (!response.ok) {\n throw new Error(\n `Failed to download ${file.path} (HTTP ${response.status})`,\n );\n }\n\n const bytes = Buffer.from(await response.arrayBuffer());\n if (bytes.byteLength !== file.size) {\n throw new Error(`Downloaded size mismatch for ${file.path}`);\n }\n if (sha256(bytes) !== file.sha256) {\n throw new Error(`Downloaded hash mismatch for ${file.path}`);\n }\n\n const outputPath = outputPathForHostedFile(destination, file.path);\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, bytes);\n}\n\nexport async function cloneHostedSite(\n options: CloneHostedSiteOptions,\n): Promise<CloneHostedSiteResult> {\n const publicSlug = publicSlugFromSite(options.site);\n const dirStatus = checkDirectoryStatus(options.destination);\n if (dirStatus.exists && !dirStatus.empty) {\n throw new Error(`Directory \"${options.destination}\" is not empty`);\n }\n\n options.onProgress?.({ phase: \"checking\" });\n const hostedSite = await getHostedSiteFiles(publicSlug);\n\n options.onProgress?.({\n phase: \"creating\",\n fileCount: hostedSite.fileCount,\n });\n await mkdir(options.destination, { recursive: true });\n\n for (const file of hostedSite.files) {\n options.onProgress?.({ phase: \"downloading\", path: file.path });\n await downloadHostedFile(file, options.destination);\n }\n\n return {\n siteId: hostedSite.siteId,\n deploymentId: hostedSite.deploymentId,\n publicSlug: hostedSite.publicSlug,\n url: hostedSite.url,\n destination: options.destination,\n fileCount: hostedSite.fileCount,\n size: hostedSite.size,\n };\n}\n"],"mappings":"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","names":["createHash","dirname","relative","resolve","sep","relative","sep","resolve","createHash","dirname","formatBytes"]}
1
+ {"version":3,"sources":["../src/commands/zero/host/index.ts","../src/lib/host/publish-static-site.ts","../src/lib/host/static-site.ts","../src/commands/zero/host/clone.ts","../src/lib/host/clone-hosted-site.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport {\n hostedArtifactKindSchema,\n type HostedArtifactKind,\n} from \"@vm0/api-contracts/contracts/zero-host\";\nimport { withErrorHandler } from \"../../../lib/command\";\nimport { publishStaticSite } from \"../../../lib/host/publish-static-site\";\nimport { cloneHostedSiteCommand } from \"./clone\";\n\ninterface HostOptions {\n readonly site?: string;\n readonly slugSuffix?: string;\n readonly artifactKind?: HostedArtifactKind;\n readonly spa?: boolean;\n readonly json?: boolean;\n}\n\nfunction parseArtifactKind(value: string): HostedArtifactKind {\n return hostedArtifactKindSchema.parse(value);\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nexport const zeroHostCommand = new Command()\n .name(\"host\")\n .description(\"Publish static sites and clone owned hosted site files\")\n .argument(\"<dir>\", \"Static build directory, for example ./dist\")\n .option(\"--site <slug>\", \"Public site slug, e.g. my-product-demo\")\n .option(\"--slug-suffix <suffix>\", \"Reuse a generated site URL suffix\")\n .option(\n \"--artifact-kind <kind>\",\n \"Artifact kind to record for this hosted deployment\",\n parseArtifactKind,\n )\n .option(\"--spa\", \"Serve unknown HTML navigation paths from index.html\")\n .option(\"--json\", \"Output only the final result as JSON\")\n .addCommand(cloneHostedSiteCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n Publish a Vite build: zero host ./dist --site my-product-demo --spa\n Redeploy a URL: zero host ./dist --site my-product-demo --slug-suffix a1b2c3d4 --spa\n Clone a hosted site: zero host clone my-product-demo-a1b2c3d4-release-01 ./site\n Machine readable: zero host ./dist --site my-product-demo --spa --json\n\nNotes:\n - Authenticates via ZERO_TOKEN (publish requires host:write; clone requires host:read)\n - Reusing both --site and --slug-suffix keeps the same URL\n - The directory must include index.html\n - Local HTML/CSS asset references must point at files inside the directory`,\n )\n .action(\n withErrorHandler(async (dir: string, options: HostOptions) => {\n if (!options.site) {\n throw new Error(\"--site is required when publishing a hosted site\");\n }\n const result = await publishStaticSite({\n dir,\n site: options.site,\n slugSuffix: options.slugSuffix,\n artifactKind: options.artifactKind,\n spaFallback: Boolean(options.spa),\n onProgress: options.json\n ? undefined\n : (progress) => {\n if (progress.phase === \"preparing\") {\n console.log(\n chalk.dim(`Preparing ${progress.fileCount} files...`),\n );\n return;\n }\n console.log(chalk.dim(`Uploading ${progress.path}`));\n },\n });\n\n if (options.json) {\n console.log(JSON.stringify(result));\n return;\n }\n\n console.log(chalk.green(\"✓ Hosted site ready\"));\n console.log(chalk.dim(` Site: ${result.publicSlug}`));\n console.log(chalk.dim(` Deployment: ${result.deploymentId}`));\n console.log(chalk.dim(` Files: ${result.fileCount.toLocaleString()}`));\n console.log(chalk.dim(` Size: ${formatBytes(result.size)}`));\n console.log(` URL: ${result.url}`);\n }),\n );\n","import type { HostedArtifactKind } from \"@vm0/api-contracts/contracts/zero-host\";\nimport { completeHostedSite, prepareHostedSite } from \"../api\";\nimport { readStaticSiteFile, scanStaticSite } from \"./static-site\";\n\ninterface PublishStaticSiteProgress {\n readonly phase: \"preparing\" | \"uploading\";\n readonly fileCount?: number;\n readonly path?: string;\n}\n\ninterface PublishStaticSiteResult {\n readonly siteId: string;\n readonly deploymentId: string;\n readonly publicSlug: string;\n readonly url: string;\n readonly fileCount: number;\n readonly size: number;\n}\n\ninterface PublishStaticSiteOptions {\n readonly dir: string;\n readonly site: string;\n readonly slugSuffix?: string;\n readonly artifactKind?: HostedArtifactKind;\n readonly spaFallback?: boolean;\n readonly onProgress?: (progress: PublishStaticSiteProgress) => void;\n}\n\nexport async function publishStaticSite(\n options: PublishStaticSiteOptions,\n): Promise<PublishStaticSiteResult> {\n const artifactKind = options.artifactKind ?? \"hosted-site\";\n const scan = await scanStaticSite(\n options.dir,\n artifactKind === \"hosted-site\" ? { defaultRobots: \"disallow-all\" } : {},\n );\n const totalSize = scan.files.reduce((sum, file) => {\n return sum + file.size;\n }, 0);\n\n options.onProgress?.({\n phase: \"preparing\",\n fileCount: scan.files.length,\n });\n\n const prepared = await prepareHostedSite({\n site: options.site,\n ...(options.slugSuffix !== undefined && { slugSuffix: options.slugSuffix }),\n artifactKind,\n spaFallback: Boolean(options.spaFallback),\n files: scan.files.map((file) => {\n return {\n path: file.path,\n size: file.size,\n sha256: file.sha256,\n contentType: file.contentType,\n immutable: file.immutable,\n };\n }),\n });\n\n const uploadByPath = new Map(\n prepared.uploads.map((upload) => {\n return [upload.path, upload.uploadUrl];\n }),\n );\n\n for (const file of scan.files) {\n const uploadUrl = uploadByPath.get(file.path);\n if (!uploadUrl) {\n throw new Error(`Missing upload URL for ${file.path}`);\n }\n options.onProgress?.({ phase: \"uploading\", path: file.path });\n const bytes = await readStaticSiteFile(file);\n const response = await fetch(uploadUrl, {\n method: \"PUT\",\n headers: { \"Content-Type\": file.contentType },\n body: new Uint8Array(bytes),\n });\n if (!response.ok) {\n throw new Error(\n `Failed to upload ${file.path} (HTTP ${response.status})`,\n );\n }\n }\n\n const completed = await completeHostedSite(prepared.deploymentId);\n\n return {\n siteId: completed.siteId,\n deploymentId: completed.deploymentId,\n publicSlug: completed.publicSlug,\n url: completed.url,\n fileCount: scan.files.length,\n size: totalSize,\n };\n}\n","import { createHash } from \"node:crypto\";\nimport { readdir, readFile, stat } from \"node:fs/promises\";\nimport { extname, relative, resolve, sep, dirname, posix } from \"node:path\";\n\ninterface StaticSiteFile {\n readonly absolutePath?: string;\n readonly content?: Uint8Array;\n readonly path: string;\n readonly size: number;\n readonly sha256: string;\n readonly contentType: string;\n readonly immutable?: boolean;\n}\n\ninterface StaticSiteScanOptions {\n readonly defaultRobots?: \"disallow-all\";\n}\n\ninterface StaticSiteScanResult {\n readonly root: string;\n readonly files: readonly StaticSiteFile[];\n}\n\nexport const DEFAULT_HOSTED_SITE_ROBOTS_TXT = \"User-agent: *\\nDisallow: /\\n\";\n\nconst MIME_BY_EXTENSION: Record<string, string> = {\n \".html\": \"text/html; charset=utf-8\",\n \".htm\": \"text/html; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".js\": \"application/javascript; charset=utf-8\",\n \".mjs\": \"application/javascript; charset=utf-8\",\n \".json\": \"application/json; charset=utf-8\",\n \".map\": \"application/json; charset=utf-8\",\n \".txt\": \"text/plain; charset=utf-8\",\n \".xml\": \"application/xml; charset=utf-8\",\n \".svg\": \"image/svg+xml; charset=utf-8\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".avif\": \"image/avif\",\n \".ico\": \"image/x-icon\",\n \".wasm\": \"application/wasm\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".otf\": \"font/otf\",\n \".eot\": \"application/vnd.ms-fontobject\",\n \".mp4\": \"video/mp4\",\n \".webm\": \"video/webm\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n};\n\nconst HTML_REFERENCE_RE =\n /<(?:script|link|img|source|video|audio|embed|object)\\b[^>]*\\s(?:src|href|poster|data)=[\"']([^\"']+)[\"'][^>]*>/giu;\nconst SRCSET_RE = /\\s(?:srcset)=[\"']([^\"']+)[\"']/giu;\nconst CSS_URL_RE = /url\\(\\s*[\"']?([^\"')]+)[\"']?\\s*\\)/giu;\nconst CSS_IMPORT_RE = /@import\\s+(?:url\\()?[\"']([^\"']+)[\"']\\)?/giu;\n\nfunction inferContentType(path: string): string {\n return (\n MIME_BY_EXTENSION[extname(path).toLowerCase()] ?? \"application/octet-stream\"\n );\n}\n\nfunction looksImmutable(path: string): boolean {\n if (path.startsWith(\"/assets/\")) {\n return true;\n }\n return /(?:[-.])[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9]+$/u.test(path);\n}\n\nfunction toSitePath(root: string, absolutePath: string): string {\n const rel = relative(root, absolutePath).split(sep).join(\"/\");\n return `/${rel}`;\n}\n\nfunction isSafeSitePath(path: string): boolean {\n if (!path.startsWith(\"/\") || path.startsWith(\"//\")) {\n return false;\n }\n if (path.includes(\"\\\\\") || path.includes(\"\\0\")) {\n return false;\n }\n const segments = path.split(\"/\").filter(Boolean);\n return !segments.some((segment) => {\n return segment === \".\" || segment === \"..\";\n });\n}\n\nfunction isExternalReference(value: string): boolean {\n return /^(?:[a-z][a-z0-9+.-]*:|\\/\\/|#)/iu.test(value);\n}\n\n// References containing template interpolation are resolved at runtime, not on\n// disk. Covers JS template literals (`${...}`), mustache/Vue/Angular/Handlebars\n// (`{{...}}`), and EJS/ERB (`<%...%>`). These cannot be validated statically.\nfunction isDynamicReference(value: string): boolean {\n return /\\$\\{|\\{\\{|<%/u.test(value);\n}\n\nfunction stripQueryAndHash(value: string): string {\n const hashIndex = value.indexOf(\"#\");\n const withoutHash = hashIndex >= 0 ? value.slice(0, hashIndex) : value;\n const queryIndex = withoutHash.indexOf(\"?\");\n return queryIndex >= 0 ? withoutHash.slice(0, queryIndex) : withoutHash;\n}\n\nfunction normalizeReference(fromPath: string, raw: string): string | null {\n const trimmed = raw.trim();\n if (!trimmed || isExternalReference(trimmed) || isDynamicReference(trimmed)) {\n return null;\n }\n const stripped = stripQueryAndHash(trimmed);\n if (!stripped || stripped.endsWith(\"/\")) {\n return null;\n }\n const resolved = stripped.startsWith(\"/\")\n ? posix.normalize(stripped)\n : posix.normalize(posix.join(dirname(fromPath), stripped));\n const path = resolved.startsWith(\"/\") ? resolved : `/${resolved}`;\n if (!isSafeSitePath(path)) {\n throw new Error(`Invalid asset reference in ${fromPath}: ${raw}`);\n }\n return path;\n}\n\nfunction shouldRequireHtmlReference(path: string): boolean {\n return extname(path).length > 0 || path.startsWith(\"/assets/\");\n}\n\nfunction isHtmlExtension(ext: string): boolean {\n return ext === \".html\" || ext === \".htm\";\n}\n\nfunction shouldValidateReferences(ext: string): boolean {\n return isHtmlExtension(ext) || ext === \".css\";\n}\n\nfunction collectSrcsetReferences(value: string): string[] {\n return value\n .split(\",\")\n .map((entry) => {\n return entry.trim().split(/\\s+/u)[0] ?? \"\";\n })\n .filter(Boolean);\n}\n\nfunction collectHtmlReferences(text: string): string[] {\n const references: string[] = [];\n for (const match of text.matchAll(HTML_REFERENCE_RE)) {\n if (match[1]) references.push(match[1]);\n }\n for (const match of text.matchAll(SRCSET_RE)) {\n if (!match[1]) continue;\n references.push(...collectSrcsetReferences(match[1]));\n }\n return references;\n}\n\nfunction collectCssReferences(text: string): string[] {\n const references: string[] = [];\n for (const match of text.matchAll(CSS_URL_RE)) {\n if (match[1]) references.push(match[1]);\n }\n for (const match of text.matchAll(CSS_IMPORT_RE)) {\n if (match[1]) references.push(match[1]);\n }\n return references;\n}\n\nfunction collectReferences(ext: string, text: string): string[] {\n return isHtmlExtension(ext)\n ? collectHtmlReferences(text)\n : collectCssReferences(text);\n}\n\nasync function hashFile(path: string): Promise<string> {\n const bytes = await readFile(path);\n return createHash(\"sha256\").update(bytes).digest(\"hex\");\n}\n\nfunction textFile(path: string, content: string): StaticSiteFile {\n const bytes = new TextEncoder().encode(content);\n return {\n content: bytes,\n path,\n size: bytes.byteLength,\n sha256: createHash(\"sha256\").update(bytes).digest(\"hex\"),\n contentType: inferContentType(path),\n };\n}\n\nfunction ensureDefaultRobots(\n files: readonly StaticSiteFile[],\n options: StaticSiteScanOptions,\n): readonly StaticSiteFile[] {\n if (\n options.defaultRobots !== \"disallow-all\" ||\n files.some((file) => {\n return file.path === \"/robots.txt\";\n })\n ) {\n return files;\n }\n\n return [...files, textFile(\"/robots.txt\", DEFAULT_HOSTED_SITE_ROBOTS_TXT)];\n}\n\nasync function walk(\n root: string,\n dir: string,\n files: StaticSiteFile[],\n): Promise<void> {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = resolve(dir, entry.name);\n if (entry.isDirectory()) {\n await walk(root, fullPath, files);\n continue;\n }\n if (!entry.isFile()) {\n throw new Error(`Unsupported file type in hosted site: ${fullPath}`);\n }\n\n const fileStat = await stat(fullPath);\n const path = toSitePath(root, fullPath);\n if (!isSafeSitePath(path)) {\n throw new Error(`Invalid hosted-site path: ${path}`);\n }\n files.push({\n absolutePath: fullPath,\n path,\n size: fileStat.size,\n sha256: await hashFile(fullPath),\n contentType: inferContentType(path),\n immutable: looksImmutable(path) || undefined,\n });\n }\n}\n\nasync function assertReferencesExist(\n files: readonly StaticSiteFile[],\n): Promise<void> {\n const byPath = new Map(\n files.map((file) => {\n return [file.path, file];\n }),\n );\n\n for (const file of files) {\n const ext = extname(file.path).toLowerCase();\n if (!shouldValidateReferences(ext)) {\n continue;\n }\n if (!file.absolutePath) {\n throw new Error(`Hosted-site file has no source: ${file.path}`);\n }\n const text = await readFile(file.absolutePath, \"utf8\");\n const references = collectReferences(ext, text);\n\n for (const reference of references) {\n const normalized = normalizeReference(file.path, reference);\n if (!normalized) {\n continue;\n }\n if (isHtmlExtension(ext) && !shouldRequireHtmlReference(normalized)) {\n continue;\n }\n if (!byPath.has(normalized)) {\n throw new Error(\n `Missing asset referenced by ${file.path}: ${reference}`,\n );\n }\n }\n }\n}\n\nexport async function scanStaticSite(\n rootPath: string,\n options: StaticSiteScanOptions = {},\n): Promise<StaticSiteScanResult> {\n const root = resolve(rootPath);\n const rootStat = await stat(root);\n if (!rootStat.isDirectory()) {\n throw new Error(`Hosted site path must be a directory: ${rootPath}`);\n }\n\n const files: StaticSiteFile[] = [];\n await walk(root, root, files);\n\n if (\n !files.some((file) => {\n return file.path === \"/index.html\";\n })\n ) {\n throw new Error(\"Hosted site directory must include index.html\");\n }\n\n await assertReferencesExist(files);\n const publishFiles = [...ensureDefaultRobots(files, options)];\n\n return {\n root,\n files: publishFiles.sort((a, b) => {\n return a.path.localeCompare(b.path);\n }),\n };\n}\n\nexport async function readStaticSiteFile(\n file: StaticSiteFile,\n): Promise<Uint8Array> {\n if (file.content) {\n return file.content;\n }\n if (!file.absolutePath) {\n throw new Error(`Hosted-site file has no source: ${file.path}`);\n }\n const bytes = await readFile(file.absolutePath);\n return new Uint8Array(bytes);\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\n\nimport { withErrorHandler } from \"../../../lib/command\";\nimport {\n cloneHostedSite,\n publicSlugFromSite,\n} from \"../../../lib/host/clone-hosted-site\";\nimport { formatBytes } from \"../../../lib/utils/file-utils\";\n\ninterface CloneOptions {\n readonly json?: boolean;\n}\n\nfunction jsonOption(options: CloneOptions, command: Command): boolean {\n const parentOptions = command.parent?.opts<CloneOptions>();\n return Boolean(options.json || parentOptions?.json);\n}\n\nexport const cloneHostedSiteCommand = new Command()\n .name(\"clone\")\n .description(\"Clone an owned hosted site's active files to a local directory\")\n .argument(\"<site>\", \"Hosted site public slug or URL\")\n .argument(\"[destination]\", \"Destination directory (default: public slug)\")\n .option(\"--json\", \"Output only the final result as JSON\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Clone by public slug: zero host clone my-site-a1b2c3d4-release-01\n Clone by hosted URL: zero host clone https://my-site-a1b2c3d4-release-01.sites.example.com ./site\n Machine readable: zero host clone my-site-a1b2c3d4-release-01 --json\n\nNotes:\n - Authenticates via ZERO_TOKEN (requires host:read capability)\n - Only hosted sites owned by the active org can be cloned\n - Downloads files directly from R2 and verifies size/hash\n - The destination directory must be empty or not exist`,\n )\n .action(\n withErrorHandler(\n async (\n site: string,\n destination: string | undefined,\n options: CloneOptions,\n command: Command,\n ) => {\n const json = jsonOption(options, command);\n const targetDir = destination ?? publicSlugFromSite(site);\n const result = await cloneHostedSite({\n site,\n destination: targetDir,\n onProgress: json\n ? undefined\n : (progress) => {\n if (progress.phase === \"checking\") {\n console.log(chalk.dim(\"Checking hosted site...\"));\n return;\n }\n if (progress.phase === \"creating\") {\n console.log(\n chalk.dim(\n `Preparing ${progress.fileCount?.toLocaleString() ?? 0} files...`,\n ),\n );\n return;\n }\n console.log(chalk.dim(`Downloading ${progress.path}`));\n },\n });\n\n if (json) {\n console.log(JSON.stringify(result));\n return;\n }\n\n console.log(chalk.green(\"✓ Hosted site cloned\"));\n console.log(chalk.dim(` Site: ${result.publicSlug}`));\n console.log(chalk.dim(` Deployment: ${result.deploymentId}`));\n console.log(chalk.dim(` Files: ${result.fileCount.toLocaleString()}`));\n console.log(chalk.dim(` Size: ${formatBytes(result.size)}`));\n console.log(chalk.dim(` Location: ${result.destination}/`));\n console.log(` URL: ${result.url}`);\n },\n ),\n );\n","import { createHash } from \"node:crypto\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, relative, resolve, sep } from \"node:path\";\n\nimport type { HostedSiteFilesResponse } from \"@vm0/api-contracts/contracts/zero-host\";\nimport { getHostedSiteFiles } from \"../api\";\nimport { checkDirectoryStatus } from \"../utils/file-utils\";\n\ninterface CloneHostedSiteProgress {\n readonly phase: \"checking\" | \"creating\" | \"downloading\";\n readonly fileCount?: number;\n readonly path?: string;\n}\n\ninterface CloneHostedSiteResult {\n readonly siteId: string;\n readonly deploymentId: string;\n readonly publicSlug: string;\n readonly url: string;\n readonly destination: string;\n readonly fileCount: number;\n readonly size: number;\n}\n\ninterface CloneHostedSiteOptions {\n readonly site: string;\n readonly destination: string;\n readonly onProgress?: (progress: CloneHostedSiteProgress) => void;\n}\n\nexport function publicSlugFromSite(value: string): string {\n const trimmed = value.trim();\n if (URL.canParse(trimmed)) {\n const url = new URL(trimmed);\n return url.hostname.split(\".\")[0] ?? trimmed;\n }\n if (trimmed.includes(\".\")) {\n return trimmed.split(\".\")[0] ?? trimmed;\n }\n return trimmed;\n}\n\nfunction isInsideDirectory(parent: string, target: string): boolean {\n const relativePath = relative(parent, target);\n return (\n relativePath === \"\" ||\n (!relativePath.startsWith(`..${sep}`) &&\n relativePath !== \"..\" &&\n !isAbsolute(relativePath))\n );\n}\n\nfunction outputPathForHostedFile(\n destination: string,\n hostedPath: string,\n): string {\n if (\n !hostedPath.startsWith(\"/\") ||\n hostedPath.startsWith(\"//\") ||\n hostedPath.includes(\"\\\\\") ||\n hostedPath.includes(\"\\0\")\n ) {\n throw new Error(`Invalid hosted-site path: ${hostedPath}`);\n }\n\n const segments = hostedPath.split(\"/\").filter((segment) => {\n return segment.length > 0;\n });\n if (\n segments.length === 0 ||\n segments.some((segment) => {\n return segment === \".\" || segment === \"..\";\n })\n ) {\n throw new Error(`Invalid hosted-site path: ${hostedPath}`);\n }\n\n const destinationRoot = resolve(destination);\n const outputPath = resolve(destinationRoot, ...segments);\n if (!isInsideDirectory(destinationRoot, outputPath)) {\n throw new Error(`Invalid hosted-site path: ${hostedPath}`);\n }\n\n return outputPath;\n}\n\nfunction sha256(bytes: Buffer): string {\n return createHash(\"sha256\").update(bytes).digest(\"hex\");\n}\n\nasync function downloadHostedFile(\n file: HostedSiteFilesResponse[\"files\"][number],\n destination: string,\n): Promise<void> {\n const response = await fetch(file.downloadUrl);\n if (!response.ok) {\n throw new Error(\n `Failed to download ${file.path} (HTTP ${response.status})`,\n );\n }\n\n const bytes = Buffer.from(await response.arrayBuffer());\n if (bytes.byteLength !== file.size) {\n throw new Error(`Downloaded size mismatch for ${file.path}`);\n }\n if (sha256(bytes) !== file.sha256) {\n throw new Error(`Downloaded hash mismatch for ${file.path}`);\n }\n\n const outputPath = outputPathForHostedFile(destination, file.path);\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, bytes);\n}\n\nexport async function cloneHostedSite(\n options: CloneHostedSiteOptions,\n): Promise<CloneHostedSiteResult> {\n const publicSlug = publicSlugFromSite(options.site);\n const dirStatus = checkDirectoryStatus(options.destination);\n if (dirStatus.exists && !dirStatus.empty) {\n throw new Error(`Directory \"${options.destination}\" is not empty`);\n }\n\n options.onProgress?.({ phase: \"checking\" });\n const hostedSite = await getHostedSiteFiles(publicSlug);\n\n options.onProgress?.({\n phase: \"creating\",\n fileCount: hostedSite.fileCount,\n });\n await mkdir(options.destination, { recursive: true });\n\n for (const file of hostedSite.files) {\n options.onProgress?.({ phase: \"downloading\", path: file.path });\n await downloadHostedFile(file, options.destination);\n }\n\n return {\n siteId: hostedSite.siteId,\n deploymentId: hostedSite.deploymentId,\n publicSlug: hostedSite.publicSlug,\n url: hostedSite.url,\n destination: options.destination,\n fileCount: hostedSite.fileCount,\n size: hostedSite.size,\n };\n}\n"],"mappings":"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","names":["createHash","dirname","relative","resolve","sep","relative","sep","resolve","createHash","dirname","formatBytes"]}
package/index.js CHANGED
@@ -36,14 +36,13 @@ import {
36
36
  renderRunCreated,
37
37
  require_dist,
38
38
  showNextSteps
39
- } from "./chunk-3LJFZEZ5.js";
39
+ } from "./chunk-OCOHCUE3.js";
40
40
  import {
41
41
  Kn,
42
42
  uo
43
43
  } from "./chunk-J4HTPZIN.js";
44
44
  import "./chunk-GU4IPLKQ.js";
45
- import "./chunk-NBAZLPV3.js";
46
- import "./chunk-ADBNTM34.js";
45
+ import "./chunk-H4Y7JDZB.js";
47
46
  import {
48
47
  isInteractive,
49
48
  promptText
@@ -76,7 +75,7 @@ import {
76
75
  prepareStorage,
77
76
  searchLogs,
78
77
  volumeConfigSchema
79
- } from "./chunk-XX3HVOWG.js";
78
+ } from "./chunk-GIACTMOF.js";
80
79
  import "./chunk-LTDQISD7.js";
81
80
  import {
82
81
  ApiRequestError,
@@ -88,14 +87,12 @@ import {
88
87
  headersWithCliClientHeaders,
89
88
  loadConfig,
90
89
  saveConfig,
90
+ source_default,
91
91
  withErrorHandler
92
- } from "./chunk-22VWTDX6.js";
93
- import {
94
- source_default
95
- } from "./chunk-JUTUEPIR.js";
92
+ } from "./chunk-VC7E6IA7.js";
96
93
  import {
97
94
  configureGlobalProxyFromEnv
98
- } from "./chunk-NAFRQSTL.js";
95
+ } from "./chunk-T3XOMNS6.js";
99
96
  import "./chunk-LRHXR7JT.js";
100
97
  import {
101
98
  Command,
@@ -433,7 +430,7 @@ function getConfigPath() {
433
430
  return join(os.homedir(), ".vm0", "config.json");
434
431
  }
435
432
  var infoCommand = new Command().name("info").description("Display environment and debug information").action(async () => {
436
- console.log(source_default.bold(`VM0 CLI v${"9.238.3"}`));
433
+ console.log(source_default.bold(`VM0 CLI v${"9.238.5"}`));
437
434
  console.log();
438
435
  const config = await loadConfig();
439
436
  const hasEnvToken = !!process.env.VM0_TOKEN;
@@ -1136,7 +1133,7 @@ var composeCommand = new Command().name("compose").description("Create or update
1136
1133
  options.autoUpdate = false;
1137
1134
  }
1138
1135
  if (options.autoUpdate !== false) {
1139
- await startSilentUpgrade("9.238.3");
1136
+ await startSilentUpgrade("9.238.5");
1140
1137
  }
1141
1138
  try {
1142
1139
  const { config, agentName, agent, basePath } = await loadAndValidateConfig(resolvedConfigFile);
@@ -1233,7 +1230,7 @@ var mainRunCommand = new Command().name("run").description("Run an agent").argum
1233
1230
  withErrorHandler(
1234
1231
  async (identifier, prompt, options) => {
1235
1232
  if (options.autoUpdate !== false) {
1236
- await startSilentUpgrade("9.238.3");
1233
+ await startSilentUpgrade("9.238.5");
1237
1234
  }
1238
1235
  const { name, version } = parseIdentifier(identifier);
1239
1236
  let composeId;
@@ -3098,13 +3095,13 @@ var upgradeCommand = new Command().name("upgrade").description("Upgrade vm0 CLI
3098
3095
  if (latestVersion === null) {
3099
3096
  throw new Error("Could not check for updates. Please try again later.");
3100
3097
  }
3101
- if (latestVersion === "9.238.3") {
3102
- console.log(source_default.green(`\u2713 Already up to date (${"9.238.3"})`));
3098
+ if (latestVersion === "9.238.5") {
3099
+ console.log(source_default.green(`\u2713 Already up to date (${"9.238.5"})`));
3103
3100
  return;
3104
3101
  }
3105
3102
  console.log(
3106
3103
  source_default.yellow(
3107
- `Current version: ${"9.238.3"} -> Latest version: ${latestVersion}`
3104
+ `Current version: ${"9.238.5"} -> Latest version: ${latestVersion}`
3108
3105
  )
3109
3106
  );
3110
3107
  console.log();
@@ -3131,7 +3128,7 @@ var upgradeCommand = new Command().name("upgrade").description("Upgrade vm0 CLI
3131
3128
  const success = await performUpgrade(packageManager);
3132
3129
  if (success) {
3133
3130
  console.log(
3134
- source_default.green(`\u2713 Upgraded from ${"9.238.3"} to ${latestVersion}`)
3131
+ source_default.green(`\u2713 Upgraded from ${"9.238.5"} to ${latestVersion}`)
3135
3132
  );
3136
3133
  return;
3137
3134
  }
@@ -3198,7 +3195,7 @@ var whoamiCommand = new Command().name("whoami").description("Show current ident
3198
3195
 
3199
3196
  // src/index.ts
3200
3197
  var program = new Command();
3201
- program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.238.3");
3198
+ program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.238.5");
3202
3199
  program.addCommand(authCommand);
3203
3200
  program.addCommand(infoCommand);
3204
3201
  program.addCommand(composeCommand);