@vm0/cli 9.278.0 → 9.278.1

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 (194) hide show
  1. package/{agent-HUDTEGLK.js → agent-4F3XAJWN.js} +12 -6
  2. package/agent-4F3XAJWN.js.map +1 -0
  3. package/{banking-BMZONEXP.js → banking-CWQFQKZB.js} +61 -7
  4. package/banking-CWQFQKZB.js.map +1 -0
  5. package/{browser-LQP445CU.js → browser-BI6UFWPH.js} +4 -5
  6. package/browser-BI6UFWPH.js.map +1 -0
  7. package/{chat-UF7QAWUT.js → chat-MKIW4FPP.js} +24 -16
  8. package/chat-MKIW4FPP.js.map +1 -0
  9. package/chunk-2SJTFDC2.js +189 -0
  10. package/chunk-2SJTFDC2.js.map +1 -0
  11. package/chunk-4FTIKZKP.js +64 -0
  12. package/chunk-4FTIKZKP.js.map +1 -0
  13. package/chunk-7UZXNER2.js +568 -0
  14. package/chunk-7UZXNER2.js.map +1 -0
  15. package/chunk-A6ZRMNM3.js +102 -0
  16. package/chunk-A6ZRMNM3.js.map +1 -0
  17. package/{chunk-QC63TUJC.js → chunk-C62A6LD6.js} +2 -2
  18. package/chunk-CCTF3YVW.js +52 -0
  19. package/chunk-CCTF3YVW.js.map +1 -0
  20. package/chunk-CD2BLKGC.js +188 -0
  21. package/chunk-CD2BLKGC.js.map +1 -0
  22. package/chunk-CEJGHPF3.js +55 -0
  23. package/chunk-CEJGHPF3.js.map +1 -0
  24. package/chunk-DUA6CF7E.js +2053 -0
  25. package/chunk-DUA6CF7E.js.map +1 -0
  26. package/chunk-E2TQAKNL.js +1300 -0
  27. package/chunk-E2TQAKNL.js.map +1 -0
  28. package/{chunk-5ZZI2LSO.js → chunk-GHKWW4NC.js} +5 -5
  29. package/chunk-GV3PG6CZ.js +114 -0
  30. package/chunk-GV3PG6CZ.js.map +1 -0
  31. package/chunk-GY7D76EZ.js +81 -0
  32. package/chunk-GY7D76EZ.js.map +1 -0
  33. package/chunk-HHHHZMTA.js +434 -0
  34. package/chunk-HHHHZMTA.js.map +1 -0
  35. package/chunk-HZYOJTEE.js +1275 -0
  36. package/chunk-HZYOJTEE.js.map +1 -0
  37. package/chunk-J3ZRXVI6.js +740 -0
  38. package/chunk-J3ZRXVI6.js.map +1 -0
  39. package/chunk-JJWFO27K.js +31 -0
  40. package/chunk-JJWFO27K.js.map +1 -0
  41. package/chunk-JV6LM2YC.js +39 -0
  42. package/chunk-JV6LM2YC.js.map +1 -0
  43. package/chunk-KER77KJB.js +105 -0
  44. package/chunk-KER77KJB.js.map +1 -0
  45. package/{chunk-V5ZVB7RJ.js → chunk-KKO2XGLQ.js} +1 -6
  46. package/chunk-KKO2XGLQ.js.map +1 -0
  47. package/chunk-LIYPTQAO.js +198 -0
  48. package/chunk-LIYPTQAO.js.map +1 -0
  49. package/chunk-LYLDVUHT.js +131 -0
  50. package/chunk-LYLDVUHT.js.map +1 -0
  51. package/chunk-PFWBO2VK.js +801 -0
  52. package/chunk-PFWBO2VK.js.map +1 -0
  53. package/chunk-RTCRU35A.js +194 -0
  54. package/chunk-RTCRU35A.js.map +1 -0
  55. package/{chunk-F2AM4RWA.js → chunk-RTEEWZUT.js} +2 -2
  56. package/{chunk-F2AM4RWA.js.map → chunk-RTEEWZUT.js.map} +1 -1
  57. package/{chunk-BRV4D3P2.js → chunk-RUKMHBNQ.js} +2 -2
  58. package/chunk-SA4DYSBR.js +31 -0
  59. package/chunk-SA4DYSBR.js.map +1 -0
  60. package/chunk-SJPOFQJU.js +792 -0
  61. package/chunk-SJPOFQJU.js.map +1 -0
  62. package/{chunk-V7A6ZFHR.js → chunk-SMPSKBAP.js} +25 -774
  63. package/chunk-SMPSKBAP.js.map +1 -0
  64. package/{chunk-E53W6UVQ.js → chunk-T2X2EGV2.js} +4 -4
  65. package/chunk-T2X2EGV2.js.map +1 -0
  66. package/chunk-U2GQH6AD.js +309 -0
  67. package/chunk-U2GQH6AD.js.map +1 -0
  68. package/chunk-U6A2RPHO.js +66 -0
  69. package/chunk-U6A2RPHO.js.map +1 -0
  70. package/chunk-UIXUGVZB.js +362 -0
  71. package/chunk-UIXUGVZB.js.map +1 -0
  72. package/chunk-XRZKJACM.js +49 -0
  73. package/chunk-XRZKJACM.js.map +1 -0
  74. package/chunk-YDS3X7KB.js +202 -0
  75. package/chunk-YDS3X7KB.js.map +1 -0
  76. package/{chunk-A6TMOGPR.js → chunk-ZKNJW4K6.js} +1412 -334
  77. package/chunk-ZKNJW4K6.js.map +1 -0
  78. package/chunk-ZXSCBS77.js +90 -0
  79. package/chunk-ZXSCBS77.js.map +1 -0
  80. package/{computer-use-RRD7BCCK.js → computer-use-6AEVW47F.js} +9 -7
  81. package/computer-use-6AEVW47F.js.map +1 -0
  82. package/{connector-XX7UU6XE.js → connector-XDQ6JEBU.js} +25 -13
  83. package/connector-XDQ6JEBU.js.map +1 -0
  84. package/{credit-GDNNAQRO.js → credit-JPQA5XPA.js} +8 -10
  85. package/credit-JPQA5XPA.js.map +1 -0
  86. package/{developer-support-IISP5UBI.js → developer-support-V7NZOU2P.js} +27 -7
  87. package/developer-support-V7NZOU2P.js.map +1 -0
  88. package/{doctor-IZM2TJOH.js → doctor-FJO24TG3.js} +13 -11
  89. package/doctor-FJO24TG3.js.map +1 -0
  90. package/{feishu-XB7SQBSI.js → feishu-PNOAM33Q.js} +99 -9
  91. package/feishu-PNOAM33Q.js.map +1 -0
  92. package/{finance-OGWHKQLU.js → finance-55OJ6GYP.js} +49 -9
  93. package/finance-55OJ6GYP.js.map +1 -0
  94. package/{generate-AA2PVOYQ.js → generate-XUKBK523.js} +26 -21
  95. package/generate-XUKBK523.js.map +1 -0
  96. package/{github-VJVIBTVF.js → github-V4MD2PMM.js} +83 -8
  97. package/github-V4MD2PMM.js.map +1 -0
  98. package/{goal-7SYVHDTK.js → goal-FS5FJKVU.js} +69 -13
  99. package/goal-FS5FJKVU.js.map +1 -0
  100. package/{host-UVQMIOBA.js → host-GITTJ6PR.js} +124 -10
  101. package/host-GITTJ6PR.js.map +1 -0
  102. package/{logs-PIS4X24E.js → logs-EEUIGYUD.js} +51 -11
  103. package/logs-EEUIGYUD.js.map +1 -0
  104. package/{mail-L33OSQ2R.js → mail-G4SAJSBD.js} +39 -8
  105. package/mail-G4SAJSBD.js.map +1 -0
  106. package/{maps-D5XTXU5U.js → maps-7ANNU3BX.js} +65 -11
  107. package/maps-7ANNU3BX.js.map +1 -0
  108. package/{model-ZFMRECDM.js → model-DSPDCJLB.js} +6 -6
  109. package/model-DSPDCJLB.js.map +1 -0
  110. package/{model-provider-EZZ2DRYZ.js → model-provider-RZQ45PNG.js} +6 -6
  111. package/model-provider-RZQ45PNG.js.map +1 -0
  112. package/package.json +1 -1
  113. package/{people-search-PFTIO2QS.js → people-search-I7PUMF5M.js} +22 -6
  114. package/people-search-I7PUMF5M.js.map +1 -0
  115. package/{phone-6SG5ZUNL.js → phone-SSAPGMTW.js} +90 -9
  116. package/phone-SSAPGMTW.js.map +1 -0
  117. package/{recognize-LLU6J3SW.js → recognize-D7VORZBN.js} +27 -9
  118. package/recognize-D7VORZBN.js.map +1 -0
  119. package/{resource-FGUSXS4G.js → resource-76IV3TMW.js} +21 -7
  120. package/resource-76IV3TMW.js.map +1 -0
  121. package/{scrape-BAUZ2YFD.js → scrape-JBDLNTLB.js} +22 -6
  122. package/scrape-JBDLNTLB.js.map +1 -0
  123. package/{search-DLO5RXRM.js → search-UNZNUTZX.js} +29 -9
  124. package/search-UNZNUTZX.js.map +1 -0
  125. package/{slack-CVATPKP3.js → slack-AAH6GG2W.js} +103 -11
  126. package/slack-AAH6GG2W.js.map +1 -0
  127. package/{teams-ZZYO6YIK.js → teams-6OPXE4TX.js} +90 -9
  128. package/teams-6OPXE4TX.js.map +1 -0
  129. package/{telegram-VY7T4YAR.js → telegram-RRZG73RT.js} +101 -10
  130. package/telegram-RRZG73RT.js.map +1 -0
  131. package/{upgrade-GFA4ZUU4.js → upgrade-I5IL4UQL.js} +3 -4
  132. package/upgrade-I5IL4UQL.js.map +1 -0
  133. package/{video-STFG7BET.js → video-HV44W4X7.js} +5 -4
  134. package/video-HV44W4X7.js.map +1 -0
  135. package/{weather-ISJEHJWR.js → weather-EQ7CSADB.js} +70 -16
  136. package/weather-EQ7CSADB.js.map +1 -0
  137. package/{web-YN4CVHK7.js → web-6LIMWEOZ.js} +5 -5
  138. package/web-6LIMWEOZ.js.map +1 -0
  139. package/{web-search-PC7IECND.js → web-search-AT7WONZN.js} +22 -6
  140. package/web-search-AT7WONZN.js.map +1 -0
  141. package/{whoami-KXFXZGM6.js → whoami-RKTLLSI4.js} +16 -7
  142. package/whoami-RKTLLSI4.js.map +1 -0
  143. package/{workflow-O7YZHB7A.js → workflow-ZH32P622.js} +135 -39
  144. package/workflow-ZH32P622.js.map +1 -0
  145. package/zero.js +40 -40
  146. package/agent-HUDTEGLK.js.map +0 -1
  147. package/banking-BMZONEXP.js.map +0 -1
  148. package/browser-LQP445CU.js.map +0 -1
  149. package/chat-UF7QAWUT.js.map +0 -1
  150. package/chunk-2W73DZDW.js +0 -32
  151. package/chunk-2W73DZDW.js.map +0 -1
  152. package/chunk-6PN6QGIM.js +0 -11405
  153. package/chunk-6PN6QGIM.js.map +0 -1
  154. package/chunk-A6TMOGPR.js.map +0 -1
  155. package/chunk-ANOLYIPL.js +0 -10
  156. package/chunk-ANOLYIPL.js.map +0 -1
  157. package/chunk-E53W6UVQ.js.map +0 -1
  158. package/chunk-V5ZVB7RJ.js.map +0 -1
  159. package/chunk-V7A6ZFHR.js.map +0 -1
  160. package/computer-use-RRD7BCCK.js.map +0 -1
  161. package/connector-XX7UU6XE.js.map +0 -1
  162. package/credit-GDNNAQRO.js.map +0 -1
  163. package/developer-support-IISP5UBI.js.map +0 -1
  164. package/doctor-IZM2TJOH.js.map +0 -1
  165. package/feishu-XB7SQBSI.js.map +0 -1
  166. package/finance-OGWHKQLU.js.map +0 -1
  167. package/generate-AA2PVOYQ.js.map +0 -1
  168. package/github-VJVIBTVF.js.map +0 -1
  169. package/goal-7SYVHDTK.js.map +0 -1
  170. package/host-UVQMIOBA.js.map +0 -1
  171. package/logs-PIS4X24E.js.map +0 -1
  172. package/mail-L33OSQ2R.js.map +0 -1
  173. package/maps-D5XTXU5U.js.map +0 -1
  174. package/model-ZFMRECDM.js.map +0 -1
  175. package/model-provider-EZZ2DRYZ.js.map +0 -1
  176. package/people-search-PFTIO2QS.js.map +0 -1
  177. package/phone-6SG5ZUNL.js.map +0 -1
  178. package/recognize-LLU6J3SW.js.map +0 -1
  179. package/resource-FGUSXS4G.js.map +0 -1
  180. package/scrape-BAUZ2YFD.js.map +0 -1
  181. package/search-DLO5RXRM.js.map +0 -1
  182. package/slack-CVATPKP3.js.map +0 -1
  183. package/teams-ZZYO6YIK.js.map +0 -1
  184. package/telegram-VY7T4YAR.js.map +0 -1
  185. package/upgrade-GFA4ZUU4.js.map +0 -1
  186. package/video-STFG7BET.js.map +0 -1
  187. package/weather-ISJEHJWR.js.map +0 -1
  188. package/web-YN4CVHK7.js.map +0 -1
  189. package/web-search-PC7IECND.js.map +0 -1
  190. package/whoami-KXFXZGM6.js.map +0 -1
  191. package/workflow-O7YZHB7A.js.map +0 -1
  192. /package/{chunk-QC63TUJC.js.map → chunk-C62A6LD6.js.map} +0 -0
  193. /package/{chunk-5ZZI2LSO.js.map → chunk-GHKWW4NC.js.map} +0 -0
  194. /package/{chunk-BRV4D3P2.js.map → chunk-RUKMHBNQ.js.map} +0 -0
@@ -1 +0,0 @@
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 supportsUploadHeaders: true,\n });\n\n const fileContent = readFileSync(options.file);\n const uploadResponse = await fetch(prepared.uploadUrl, {\n method: \"PUT\",\n headers: {\n \"Content-Type\": prepared.contentType,\n ...prepared.uploadHeaders,\n },\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 +0,0 @@
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 +0,0 @@
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","../src/lib/utils/file-utils.ts","../src/commands/zero/host/versions.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\";\nimport { versionsHostedSiteCommand } from \"./versions\";\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 and inspect owned static hosted sites\")\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 legacy 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 .addCommand(versionsHostedSiteCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n Publish a Vite build: zero host ./dist --site my-product-demo --spa\n Publish next version: zero host ./dist --site my-product-demo --spa\n Reuse a legacy URL: zero host ./dist --site my-product-demo --slug-suffix release-01 --spa\n List site versions: zero host versions my-product-demo\n Clone a hosted site: zero host clone my-product-demo ./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 - With hosted artifact versions enabled, reusing --site publishes behind the same alias\n - Otherwise, reuse both --site and --slug-suffix to keep a legacy 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 deployed\"));\n console.log(chalk.dim(` Site: ${result.publicSlug}`));\n if (result.deploymentVersion !== undefined) {\n console.log(chalk.dim(` Version: v${result.deploymentVersion}`));\n }\n if (result.artifactUrl) {\n console.log(` Artifact: ${result.artifactUrl}`);\n }\n if (result.aliasUrl) {\n const target =\n result.isActive === false &&\n result.activeDeploymentVersion !== undefined\n ? `remains on v${result.activeDeploymentVersion}`\n : `v${result.deploymentVersion ?? \"?\"}`;\n console.log(` Alias: ${result.aliasUrl} → ${target}`);\n }\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 if (!result.aliasUrl) {\n console.log(` URL: ${result.url}`);\n }\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 deploymentVersion?: number;\n readonly artifactUrl?: string;\n readonly aliasUrl?: string;\n readonly isActive?: boolean;\n readonly activeDeploymentVersion?: number;\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 ...(completed.deploymentVersion === undefined\n ? {}\n : { deploymentVersion: completed.deploymentVersion }),\n ...(completed.artifactUrl === undefined\n ? {}\n : { artifactUrl: completed.artifactUrl }),\n ...(completed.aliasUrl === undefined\n ? {}\n : { aliasUrl: completed.aliasUrl }),\n ...(completed.isActive === undefined\n ? {}\n : { isActive: completed.isActive }),\n ...(completed.activeDeploymentVersion === undefined\n ? {}\n : { activeDeploymentVersion: completed.activeDeploymentVersion }),\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, InvalidArgumentError } 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 readonly version?: number;\n}\n\nfunction parseVersion(value: string): number {\n const version = Number(value);\n if (!Number.isSafeInteger(version) || version <= 0) {\n throw new InvalidArgumentError(\"version must be a positive integer\");\n }\n return version;\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 version to a local directory\")\n .argument(\"<site>\", \"Hosted site public slug or URL\")\n .argument(\"[destination]\", \"Destination directory (default: public slug)\")\n .option(\n \"--version <number>\",\n \"Clone a specific artifact version\",\n parseVersion,\n )\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\n Clone by hosted URL: zero host clone https://my-site.sites.example.com ./site\n Clone an artifact URL: zero host clone https://dpl-<deployment-id>.sites.example.com ./site\n Clone version 2: zero host clone my-site --version 2\n Machine readable: zero host clone my-site --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 ...(options.version === undefined\n ? {}\n : { version: options.version }),\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 if (result.deploymentVersion !== undefined) {\n console.log(chalk.dim(` Version: v${result.deploymentVersion}`));\n }\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.artifactUrl ?? 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 deploymentVersion?: number;\n readonly artifactUrl?: 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 version?: number;\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, options.version);\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 ...(hostedSite.deploymentVersion === undefined\n ? {}\n : { deploymentVersion: hostedSite.deploymentVersion }),\n ...(hostedSite.artifactUrl === undefined\n ? {}\n : { artifactUrl: hostedSite.artifactUrl }),\n destination: options.destination,\n fileCount: hostedSite.fileCount,\n size: hostedSite.size,\n };\n}\n","import * as fs from \"fs\";\n\n/**\n * Check if a directory exists and is empty (contains no files or subdirectories).\n * Returns: { exists: boolean, empty: boolean }\n * - Non-existent path: { exists: false, empty: true }\n * - Existing empty directory: { exists: true, empty: true }\n * - Existing non-empty directory: { exists: true, empty: false }\n * - Existing file (not directory): { exists: true, empty: false }\n */\nexport function checkDirectoryStatus(dirPath: string): {\n exists: boolean;\n empty: boolean;\n} {\n if (!fs.existsSync(dirPath)) {\n return { exists: false, empty: true };\n }\n\n const stat = fs.statSync(dirPath);\n if (!stat.isDirectory()) {\n // Path exists but is a file, not a directory\n return { exists: true, empty: false };\n }\n\n const entries = fs.readdirSync(dirPath);\n return { exists: true, empty: entries.length === 0 };\n}\n\n/**\n * Format bytes to human-readable format\n */\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return \"0 B\";\n const k = 1024;\n const sizes = [\"B\", \"KB\", \"MB\", \"GB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\n\nimport { getHostedSiteDeployments } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\ninterface VersionsOptions {\n readonly json?: boolean;\n}\n\nfunction jsonOption(options: VersionsOptions, command: Command): boolean {\n const parentOptions = command.parent?.opts<VersionsOptions>();\n return Boolean(options.json || parentOptions?.json);\n}\n\nexport const versionsHostedSiteCommand = new Command()\n .name(\"versions\")\n .description(\"List immutable artifact versions for an owned hosted site\")\n .argument(\"<site>\", \"Logical site slug\")\n .option(\"--json\", \"Output only the result as JSON\")\n .addHelpText(\n \"after\",\n `\nExamples:\n List versions: zero host versions my-product-demo\n Machine readable: zero host versions my-product-demo --json\n\nNotes:\n - Authenticates via ZERO_TOKEN and requires host:read\n - Requires hosted artifact versions to be enabled for the current user\n - The active marker identifies the version served by the site alias`,\n )\n .action(\n withErrorHandler(\n async (site: string, options: VersionsOptions, command: Command) => {\n const result = await getHostedSiteDeployments(site);\n if (jsonOption(options, command)) {\n console.log(JSON.stringify(result));\n return;\n }\n\n console.log(chalk.bold(`Hosted site versions: ${result.site}`));\n console.log(chalk.dim(`Alias: ${result.aliasUrl}`));\n if (result.deployments.length === 0) {\n console.log(chalk.dim(\"No deployments found\"));\n console.log(\n chalk.dim(\n `Publish one with: zero host <dir> --site ${result.site}`,\n ),\n );\n return;\n }\n\n for (const deployment of result.deployments) {\n const marker = deployment.isActive ? chalk.green(\"* \") : \" \";\n const version =\n deployment.deploymentVersion === null\n ? \"legacy\"\n : `v${deployment.deploymentVersion}`;\n const url = deployment.artifactUrl ?? result.aliasUrl;\n console.log(\n `${marker}${version} ${deployment.status} ${deployment.createdAt} ${url}`,\n );\n }\n },\n ),\n );\n"],"mappings":"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","names":["createHash","dirname","relative","resolve","sep","stat","relative","sep","resolve","createHash","dirname","jsonOption","formatBytes"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/zero/logs/index.ts","../src/commands/zero/logs/list.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { getZeroRunAgentEvents, type RunEvent } from \"../../../lib/api\";\nimport { parseTime } from \"../../../lib/utils/time-parser\";\nimport { EventStreamNormalizer } from \"../../../lib/events/event-stream-normalizer\";\nimport { EventRenderer } from \"../../../lib/events/event-renderer\";\nimport {\n collectLogItems,\n parsePositiveLogCount,\n} from \"../../../lib/utils/log-pagination\";\nimport { withErrorHandler } from \"../../../lib/command\";\nimport { isUuid } from \"../../../lib/utils/uuid\";\nimport { listCommand } from \"./list\";\nimport { searchCommand } from \"./search\";\nimport { isSupportedFramework } from \"@vm0/core/frameworks\";\n\nconst PAGE_LIMIT = 100;\n\ninterface AgentEventWithFramework {\n readonly event: RunEvent;\n readonly framework?: string;\n readonly useDefaultFramework: boolean;\n}\n\nfunction supportedLogFramework(\n framework: string | undefined,\n): string | undefined {\n return isSupportedFramework(framework) ? framework : undefined;\n}\n\nfunction hasLogFramework(framework: string | null | undefined): boolean {\n return framework !== undefined && framework !== null;\n}\n\nfunction renderAgentEvent(\n event: RunEvent,\n renderer: EventRenderer,\n normalizer: EventStreamNormalizer,\n framework: string | undefined,\n): void {\n const parsedEvents = normalizer.process(\n event.eventData,\n framework,\n new Date(event.createdAt),\n );\n for (const parsed of parsedEvents) {\n renderer.render(parsed);\n }\n}\n\nasync function showAgentEvents(\n runId: string,\n options: {\n since?: number;\n targetCount: number | \"all\";\n order: \"asc\" | \"desc\";\n },\n): Promise<void> {\n const events = await collectLogItems<AgentEventWithFramework>({\n fetchPage: async (request) => {\n const response = await getZeroRunAgentEvents(runId, request);\n const responseFramework: string | null | undefined = response.framework;\n return {\n items: response.events.map((event) => {\n const framework = supportedLogFramework(\n responseFramework ?? undefined,\n );\n return {\n event,\n ...(framework ? { framework } : {}),\n useDefaultFramework: !hasLogFramework(responseFramework),\n };\n }),\n hasMore: response.hasMore,\n nextCursor: response.nextCursor,\n };\n },\n sinceTime: options.since,\n targetCount: options.targetCount,\n order: options.order,\n pageLimit: PAGE_LIMIT,\n });\n\n if (events.length === 0) {\n console.log(chalk.yellow(\"No agent events found for this run\"));\n return;\n }\n\n const renderer = new EventRenderer({\n showTimestamp: true,\n verbose: true,\n });\n const framework = events.find((item) => {\n return item.framework !== undefined;\n })?.framework;\n const normalizer = new EventStreamNormalizer();\n\n for (const item of events) {\n renderAgentEvent(\n item.event,\n renderer,\n normalizer,\n item.framework ?? (item.useDefaultFramework ? framework : undefined),\n );\n }\n for (const parsed of normalizer.flush()) {\n renderer.render(parsed);\n }\n renderer.flush();\n}\n\nexport const zeroLogsCommand = new Command()\n .name(\"logs\")\n .description(\"View and search agent run logs\")\n .argument(\"[runId]\", \"Run ID to view agent events for\")\n .addCommand(listCommand)\n .addCommand(searchCommand)\n .option(\n \"--since <time>\",\n \"Show logs since timestamp (e.g., 5m, 2h, 1d, 2024-01-15T10:30:00Z)\",\n )\n .option(\"--tail <n>\", \"Show last N entries (default: 5)\")\n .option(\"--head <n>\", \"Show first N entries\")\n .option(\"--all\", \"Fetch all log entries\")\n .addHelpText(\n \"after\",\n `\nExamples:\n zero logs list\n zero logs <runId>\n zero logs <runId> --tail 10\n zero logs <runId> --all\n zero logs search \"error\"`,\n )\n .action(\n withErrorHandler(\n async (\n runId: string | undefined,\n options: {\n since?: string;\n tail?: string;\n head?: string;\n all?: boolean;\n },\n ) => {\n if (!runId) {\n zeroLogsCommand.help();\n return;\n }\n\n if (!isUuid(runId)) {\n console.error(\n chalk.red(`✗ Invalid run ID \"${runId}\" — expected a UUID`),\n );\n console.error(chalk.dim(\" Run: zero logs list to find run IDs\"));\n process.exit(1);\n }\n\n const countModes = [\n options.tail !== undefined,\n options.head !== undefined,\n options.all === true,\n ].filter(Boolean).length;\n if (countModes > 1) {\n throw new Error(\n \"Options --tail, --head, and --all are mutually exclusive\",\n );\n }\n\n let since: number | undefined;\n if (options.since !== undefined) {\n since = parseTime(options.since);\n }\n\n const isAll = options.all === true;\n const isHead = options.head !== undefined;\n const isTail = options.tail !== undefined;\n\n let targetCount: number | \"all\";\n if (isAll) {\n targetCount = \"all\";\n } else if (isHead) {\n targetCount = parsePositiveLogCount(options.head!, \"--head\");\n } else if (isTail) {\n targetCount = parsePositiveLogCount(options.tail!, \"--tail\");\n } else {\n targetCount = 5;\n }\n\n const order: \"asc\" | \"desc\" = isHead ? \"asc\" : \"desc\";\n\n await showAgentEvents(runId, { since, targetCount, order });\n },\n ),\n );\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { listZeroLogs } from \"../../../lib/api\";\nimport { parseTime } from \"../../../lib/utils/time-parser\";\nimport { formatIsoTimestamp } from \"../../../lib/utils/time-format\";\nimport { parseBoundedLogCount } from \"../../../lib/utils/log-pagination\";\nimport { withErrorHandler } from \"../../../lib/command\";\nimport { isUuid } from \"../../../lib/utils/uuid\";\n\nfunction formatStatus(status: string): string {\n switch (status) {\n case \"completed\":\n return chalk.green(status);\n case \"failed\":\n case \"timeout\":\n return chalk.red(status);\n case \"running\":\n case \"pending\":\n case \"queued\":\n return chalk.yellow(status);\n case \"cancelled\":\n return chalk.dim(status);\n default:\n return status;\n }\n}\n\nfunction formatTime(iso: string): string {\n return formatIsoTimestamp(iso);\n}\n\nexport const listCommand = new Command()\n .name(\"list\")\n .alias(\"ls\")\n .description(\"List agent run logs\")\n .option(\"--agent <id>\", \"Filter by Zero agent ID\")\n .option(\n \"--status <status>\",\n \"Filter by status (queued|pending|running|completed|failed|timeout|cancelled)\",\n )\n .option(\n \"--since <time>\",\n \"Filter runs created since (e.g., 5m, 2h, 1d, 2024-01-15T10:30:00Z)\",\n )\n .option(\"--limit <n>\", \"Maximum number of results (default: 20)\")\n .addHelpText(\n \"after\",\n `\nExamples:\n zero logs list\n zero logs list --agent 123e4567-e89b-12d3-a456-426614174000\n zero logs list --status completed --limit 10\n zero logs list --since 1h\n zero logs list --since 1d --status completed`,\n )\n .action(\n withErrorHandler(\n async (options: {\n agent?: string;\n status?: string;\n since?: string;\n limit?: string;\n }) => {\n const limit =\n options.limit !== undefined\n ? parseBoundedLogCount(options.limit, \"--limit\", 1, 100)\n : undefined;\n const since =\n options.since !== undefined ? parseTime(options.since) : undefined;\n if (options.agent !== undefined && !isUuid(options.agent)) {\n console.error(\n chalk.red(\n `✗ Invalid agent ID \"${options.agent}\" — expected a UUID`,\n ),\n );\n console.error(\n chalk.dim(\" Run: zero logs list to find agent IDs\"),\n );\n process.exit(1);\n }\n\n const result = await listZeroLogs({\n agentId: options.agent,\n status: options.status,\n since,\n limit,\n });\n\n if (result.data.length === 0) {\n console.log(chalk.dim(\"No logs found\"));\n return;\n }\n\n const nameCol = Math.max(\n 5,\n ...result.data.map((r) => {\n return (r.displayName || r.agentId || \"-\").length;\n }),\n );\n const statusCol = Math.max(\n 6,\n ...result.data.map((r) => {\n return r.status.length;\n }),\n );\n\n const header = [\n \"RUN ID\".padEnd(38),\n \"AGENT\".padEnd(nameCol),\n \"STATUS\".padEnd(statusCol),\n \"CREATED\",\n ].join(\" \");\n console.log(chalk.dim(header));\n\n for (const entry of result.data) {\n const runId = entry.id;\n const name = entry.displayName || entry.agentId || \"-\";\n const row = [\n runId.padEnd(38),\n name.padEnd(nameCol),\n formatStatus(entry.status).padEnd(statusCol),\n formatTime(entry.createdAt),\n ].join(\" \");\n console.log(row);\n }\n\n if (result.pagination.hasMore) {\n console.log();\n console.log(\n chalk.dim(\n ` Showing ${result.data.length} of more results. Use --limit to adjust.`,\n ),\n );\n }\n },\n ),\n );\n"],"mappings":"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","names":["framework"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/zero/mail/index.ts","../src/commands/zero/mail/connect.ts","../src/commands/zero/mail/shared.ts","../src/commands/zero/mail/link.ts","../src/commands/zero/mail/list.ts"],"sourcesContent":["import { Command } from \"commander\";\n\nimport { connectCommand } from \"./connect\";\nimport { linkCommand } from \"./link\";\nimport { listCommand } from \"./list\";\n\nexport const zeroMailCommand = new Command()\n .name(\"mail\")\n .description(\"Review linked Gmail drafts\")\n .addCommand(listCommand)\n .addCommand(connectCommand)\n .addCommand(linkCommand);\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport { listZeroConnectorCatalogStatus } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\nimport { resolveAgentContext } from \"../connector/agent-context\";\nimport { findConnectorStatusItem } from \"../connector/public-catalog\";\nimport { getPlatformOrigin } from \"../doctor/platform-url\";\nimport {\n MAIL_CONNECTOR_SLUG_BY_PROVIDER,\n currentAgentId,\n parseMailProvider,\n} from \"./shared\";\n\ninterface ConnectOptions {\n readonly json?: boolean;\n}\n\nexport const connectCommand = new Command()\n .name(\"connect\")\n .description(\"Get a connect or authorization link for a mail provider\")\n .argument(\"<provider>\", \"Mail provider: gmail or outlook\")\n .option(\"--json\", \"Print machine-readable JSON\")\n .action(\n withErrorHandler(async (providerValue: string, options: ConnectOptions) => {\n const provider = parseMailProvider(providerValue);\n const agentId = currentAgentId();\n const connectorSlug = MAIL_CONNECTOR_SLUG_BY_PROVIDER[provider];\n const [{ connectors }, agent, origin] = await Promise.all([\n listZeroConnectorCatalogStatus(),\n resolveAgentContext(agentId),\n getPlatformOrigin(),\n ]);\n if (!agent) {\n throw new Error(\"Agent context could not be loaded\");\n }\n const connector = findConnectorStatusItem(connectors, connectorSlug);\n if (!connector) {\n throw new Error(`${provider} is not available`);\n }\n\n const authorized = agent.authorizedConnectorSlugs.has(connectorSlug);\n const action =\n connector.connectionStatus === \"reconnect-required\" ||\n connector.connectionStatus === \"scope-mismatch\"\n ? \"reconnect\"\n : connector.connected && !authorized\n ? \"authorize\"\n : !connector.connected\n ? \"connect\"\n : \"ready\";\n const url =\n action === \"reconnect\"\n ? connector.connectionStatus === \"scope-mismatch\"\n ? `${origin}/connectors/${connectorSlug}/connect?agentId=${agentId}`\n : `${origin}/connectors`\n : action === \"authorize\"\n ? `${origin}/connectors/${connectorSlug}/authorize?agentId=${agentId}`\n : action === \"connect\"\n ? `${origin}/connectors/${connectorSlug}/connect?agentId=${agentId}`\n : null;\n\n if (options.json) {\n console.log(JSON.stringify({ provider, action, url }));\n return;\n }\n if (!url) {\n console.log(chalk.green(`✓ ${connector.label} is ready`));\n console.log(\n chalk.dim(` Sender: ${connector.connection?.externalEmail}`),\n );\n console.log(\n chalk.dim(\n \" After creating a Gmail draft: zero mail link <draft-id>\",\n ),\n );\n return;\n }\n const label =\n action === \"authorize\"\n ? `Authorize ${connector.label}`\n : action === \"reconnect\"\n ? `Reconnect ${connector.label}`\n : `Connect ${connector.label}`;\n console.log(`${label}: [${label}](${url})`);\n }),\n );\n","import type { ZeroMailProvider } from \"@vm0/api-contracts/contracts/zero-mail\";\n\nexport const MAIL_CONNECTOR_SLUG_BY_PROVIDER = {\n gmail: \"gmail\",\n outlook: \"outlook-mail\",\n} as const;\n\nexport function parseMailProvider(value: string): ZeroMailProvider {\n if (value === \"gmail\" || value === \"outlook\") {\n return value;\n }\n throw new Error(`Unsupported mail provider: ${value}`, {\n cause: new Error(\"Use gmail or outlook\"),\n });\n}\n\nexport function currentAgentId(): string {\n const agentId = process.env.ZERO_AGENT_ID?.trim();\n if (!agentId) {\n throw new Error(\"ZERO_AGENT_ID is not set\", {\n cause: new Error(\"Run this command from an active Zero agent run\"),\n });\n }\n return agentId;\n}\n","import { Command, Option } from \"commander\";\n\nimport { linkZeroMailDraft } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\nimport {\n addRequestedCallbackSearchParams,\n connectorActionCallbackAvailable,\n printCallbackTurnInstruction,\n} from \"../connector/action-url\";\nimport { currentAgentId } from \"./shared\";\n\nfunction currentChatThreadId(): string {\n const threadId = process.env.ZERO_CHAT_THREAD_ID?.trim();\n if (!threadId) {\n throw new Error(\"ZERO_CHAT_THREAD_ID is not set\", {\n cause: new Error(\"Run this command from a Zero web chat thread\"),\n });\n }\n return threadId;\n}\n\nfunction reviewUrlSearchParams(args: {\n readonly agentId: string;\n readonly callbackPrompt: string | undefined;\n}): URLSearchParams {\n const params = new URLSearchParams();\n if (args.callbackPrompt === undefined) {\n return params;\n }\n params.set(\"agentId\", args.agentId);\n addRequestedCallbackSearchParams(params, args.callbackPrompt, args.agentId);\n return params;\n}\n\nfunction mailDraftReviewUrl(\n mailDraftUrl: string,\n params: URLSearchParams,\n): string {\n const url = new URL(mailDraftUrl);\n for (const [name, value] of params) {\n url.searchParams.set(name, value);\n }\n return url.toString();\n}\n\nconst callbackPromptOption = new Option(\n \"--callback-prompt <prompt>\",\n \"Start the next web chat round with this prompt after the user sends the email\",\n);\nconst callbackPromptAvailable = connectorActionCallbackAvailable();\nif (!callbackPromptAvailable) {\n callbackPromptOption.hideHelp();\n}\nconst callbackPromptExample = callbackPromptAvailable\n ? ' zero mail link r-test-draft --callback-prompt \"Confirm the email was sent, then offer reply tracking\"\\n'\n : \"\";\nconst callbackPromptNotes = callbackPromptAvailable\n ? \" - Use --callback-prompt only when this turn links exactly one draft and needs no other callback action\\n - Callback prompts are included in the URL; keep them concise and do not include secrets\\n\"\n : \"\";\n\nexport const linkCommand = new Command()\n .name(\"link\")\n .description(\"Link an existing Gmail draft to the current web chat\")\n .argument(\"<gmail-draft-id>\", \"Gmail draft ID\")\n .addOption(callbackPromptOption)\n .addHelpText(\n \"after\",\n `\nExamples:\n zero mail link r-test-draft\n${callbackPromptExample}\nNotes:\n - Outputs the review URL to return to the user\n${callbackPromptNotes} - The user reviews the draft and sends it from the linked email card`,\n )\n .action(\n withErrorHandler(\n async (gmailDraftId: string, opts: { callbackPrompt?: string }) => {\n const agentId = currentAgentId();\n const threadId = currentChatThreadId();\n const params = reviewUrlSearchParams({\n agentId,\n callbackPrompt: opts.callbackPrompt,\n });\n const result = await linkZeroMailDraft({\n threadId,\n agentId,\n gmailDraftId,\n });\n console.log(mailDraftReviewUrl(result.mailDraftUrl, params));\n if (opts.callbackPrompt !== undefined) {\n printCallbackTurnInstruction();\n }\n },\n ),\n );\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport { listZeroConnectorCatalogStatus } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\nimport { resolveAgentContext } from \"../connector/agent-context\";\nimport { findConnectorStatusItem } from \"../connector/public-catalog\";\nimport { MAIL_CONNECTOR_SLUG_BY_PROVIDER, currentAgentId } from \"./shared\";\n\nexport const listCommand = new Command()\n .name(\"list\")\n .alias(\"ls\")\n .description(\"List Gmail and Outlook Mail availability for the current agent\")\n .action(\n withErrorHandler(async () => {\n const agentId = currentAgentId();\n const [{ connectors }, agent] = await Promise.all([\n listZeroConnectorCatalogStatus(),\n resolveAgentContext(agentId),\n ]);\n if (!agent) {\n throw new Error(\"Agent context could not be loaded\");\n }\n\n const rows = Object.entries(MAIL_CONNECTOR_SLUG_BY_PROVIDER).map(\n ([provider, connectorSlug]) => {\n const connector = findConnectorStatusItem(connectors, connectorSlug);\n const authorized = agent.authorizedConnectorSlugs.has(connectorSlug);\n const ready =\n authorized &&\n connector?.connected === true &&\n connector.connectionStatus === \"connected\";\n const sender = authorized\n ? (connector?.connection?.externalEmail ?? \"-\")\n : \"-\";\n const status = ready\n ? chalk.green(\"ready\")\n : connector?.connectionStatus === \"reconnect-required\" ||\n connector?.connectionStatus === \"scope-mismatch\"\n ? chalk.yellow(\"reconnect\")\n : connector?.connected\n ? chalk.yellow(\"authorize\")\n : chalk.dim(\"connect\");\n return { provider, sender, status };\n },\n );\n\n const providerWidth = Math.max(\n \"PROVIDER\".length,\n ...rows.map((row) => {\n return row.provider.length;\n }),\n );\n const senderWidth = Math.max(\n \"SENDER\".length,\n ...rows.map((row) => {\n return row.sender.length;\n }),\n );\n console.log(\n chalk.dim(\n [\n \"PROVIDER\".padEnd(providerWidth),\n \"SENDER\".padEnd(senderWidth),\n \"STATUS\",\n ].join(\" \"),\n ),\n );\n for (const row of rows) {\n console.log(\n [\n row.provider.padEnd(providerWidth),\n row.sender.padEnd(senderWidth),\n row.status,\n ].join(\" \"),\n );\n }\n console.log();\n console.log(\n chalk.dim(\" Run: zero mail connect gmail|outlook when needed\"),\n );\n }),\n );\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/zero/maps/index.ts"],"sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { Command, InvalidArgumentError } from \"commander\";\nimport chalk from \"chalk\";\nimport { callZeroMaps, type ZeroMapsResponse } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nconst TRAVEL_MODES = [\"driving\", \"walking\", \"bicycling\", \"transit\"] as const;\nconst PLACE_SEARCH_FIELDSETS = [\"pro\", \"enterprise\"] as const;\nconst PLACE_DETAIL_FIELDSETS = [\"essentials\", \"pro\", \"enterprise\"] as const;\nconst OSM_LAYERS = [\"roads\", \"buildings\", \"water\", \"parks\"] as const;\nconst OSM_STYLES = [\"standard\", \"guide\"] as const;\n\ntype TravelMode = (typeof TRAVEL_MODES)[number];\ntype PlaceSearchFieldset = (typeof PLACE_SEARCH_FIELDSETS)[number];\ntype PlaceDetailFieldset = (typeof PLACE_DETAIL_FIELDSETS)[number];\ntype OsmLayer = (typeof OSM_LAYERS)[number];\ntype OsmStyle = (typeof OSM_STYLES)[number];\n\ninterface JsonOption {\n json?: boolean;\n}\n\ninterface GeocodeOptions extends JsonOption {\n address: string;\n region?: string;\n}\n\ninterface ReverseGeocodeOptions extends JsonOption {\n lat: number;\n lng: number;\n}\n\ninterface DirectionsOptions extends JsonOption {\n origin: string;\n destination: string;\n mode: TravelMode;\n departureTime?: string;\n}\n\ninterface PlacesSearchOptions extends JsonOption {\n query: string;\n location?: string;\n radius?: number;\n limit: number;\n region?: string;\n fields: PlaceSearchFieldset;\n}\n\ninterface PlacesDetailsOptions extends JsonOption {\n placeId: string;\n fields: PlaceDetailFieldset;\n}\n\ninterface BBox {\n readonly west: number;\n readonly south: number;\n readonly east: number;\n readonly north: number;\n}\n\ninterface LatLng {\n readonly lat: number;\n readonly lng: number;\n}\n\ninterface OsmMarker extends LatLng {\n readonly label?: string;\n}\n\ninterface OsmAreaOptions extends JsonOption {\n bbox?: BBox;\n center?: LatLng;\n radius?: number;\n layers: readonly OsmLayer[];\n output?: string;\n}\n\ninterface OsmRenderOptions extends OsmAreaOptions {\n width: number;\n height: number;\n style: OsmStyle;\n title?: string;\n marker: readonly OsmMarker[];\n output: string;\n}\n\nfunction parseLatitude(value: string): number {\n const latitude = Number(value);\n if (!Number.isFinite(latitude) || latitude < -90 || latitude > 90) {\n throw new InvalidArgumentError(\"latitude must be a number from -90 to 90\");\n }\n return latitude;\n}\n\nfunction parseLongitude(value: string): number {\n const longitude = Number(value);\n if (!Number.isFinite(longitude) || longitude < -180 || longitude > 180) {\n throw new InvalidArgumentError(\n \"longitude must be a number from -180 to 180\",\n );\n }\n return longitude;\n}\n\nfunction parsePositiveInteger(value: string): number {\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed < 1) {\n throw new InvalidArgumentError(\"value must be a positive integer\");\n }\n return parsed;\n}\n\nfunction parseLimit(value: string): number {\n const limit = parsePositiveInteger(value);\n if (limit > 20) {\n throw new InvalidArgumentError(\"limit must be between 1 and 20\");\n }\n return limit;\n}\n\nfunction parseIntegerInRange(value: string, min: number, max: number): number {\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed < min || parsed > max) {\n throw new InvalidArgumentError(\n `value must be an integer from ${min} to ${max}`,\n );\n }\n return parsed;\n}\n\nfunction parseTravelMode(value: string): TravelMode {\n if (TRAVEL_MODES.includes(value as TravelMode)) {\n return value as TravelMode;\n }\n throw new InvalidArgumentError(\n `mode must be one of: ${TRAVEL_MODES.join(\", \")}`,\n );\n}\n\nfunction parsePlaceSearchFields(value: string): PlaceSearchFieldset {\n if (PLACE_SEARCH_FIELDSETS.includes(value as PlaceSearchFieldset)) {\n return value as PlaceSearchFieldset;\n }\n throw new InvalidArgumentError(\n `fields must be one of: ${PLACE_SEARCH_FIELDSETS.join(\", \")}`,\n );\n}\n\nfunction parsePlaceDetailFields(value: string): PlaceDetailFieldset {\n if (PLACE_DETAIL_FIELDSETS.includes(value as PlaceDetailFieldset)) {\n return value as PlaceDetailFieldset;\n }\n throw new InvalidArgumentError(\n `fields must be one of: ${PLACE_DETAIL_FIELDSETS.join(\", \")}`,\n );\n}\n\nfunction parseBBox(value: string): BBox {\n const parts = value.split(\",\").map((part) => {\n return part.trim();\n });\n if (parts.length !== 4) {\n throw new InvalidArgumentError(\"bbox must be west,south,east,north\");\n }\n const [westRaw, southRaw, eastRaw, northRaw] = parts;\n if (!westRaw || !southRaw || !eastRaw || !northRaw) {\n throw new InvalidArgumentError(\"bbox must be west,south,east,north\");\n }\n const bbox = {\n west: parseLongitude(westRaw),\n south: parseLatitude(southRaw),\n east: parseLongitude(eastRaw),\n north: parseLatitude(northRaw),\n };\n if (bbox.east <= bbox.west || bbox.north <= bbox.south) {\n throw new InvalidArgumentError(\n \"bbox east/north must be greater than west/south\",\n );\n }\n return bbox;\n}\n\nfunction parseLatLng(value: string): LatLng {\n const parts = value.split(\",\").map((part) => {\n return part.trim();\n });\n if (parts.length !== 2 || !parts[0] || !parts[1]) {\n throw new InvalidArgumentError(\"coordinates must be lat,lng\");\n }\n return {\n lat: parseLatitude(parts[0]),\n lng: parseLongitude(parts[1]),\n };\n}\n\nfunction parseOsmLayers(value: string): readonly OsmLayer[] {\n const layers = [\n ...new Set(\n value\n .split(\",\")\n .map((layer) => {\n return layer.trim();\n })\n .filter(Boolean),\n ),\n ];\n if (layers.length === 0) {\n throw new InvalidArgumentError(\"layers must include at least one value\");\n }\n const invalid = layers.find((layer) => {\n return !OSM_LAYERS.includes(layer as OsmLayer);\n });\n if (invalid) {\n throw new InvalidArgumentError(\n `layers must be drawn from: ${OSM_LAYERS.join(\", \")}`,\n );\n }\n return layers as readonly OsmLayer[];\n}\n\nfunction parseOsmStyle(value: string): OsmStyle {\n if (OSM_STYLES.includes(value as OsmStyle)) {\n return value as OsmStyle;\n }\n throw new InvalidArgumentError(\n `style must be one of: ${OSM_STYLES.join(\", \")}`,\n );\n}\n\nfunction parseOsmMarker(value: string): OsmMarker {\n const [latRaw, lngRaw, ...labelParts] = value.split(\",\");\n if (!latRaw?.trim() || !lngRaw?.trim()) {\n throw new InvalidArgumentError(\"marker must be lat,lng or lat,lng,label\");\n }\n const label = labelParts.join(\",\").trim();\n return {\n lat: parseLatitude(latRaw.trim()),\n lng: parseLongitude(lngRaw.trim()),\n ...(label ? { label } : {}),\n };\n}\n\nfunction collectOsmMarker(\n value: string,\n previous: readonly OsmMarker[],\n): readonly OsmMarker[] {\n return [...previous, parseOsmMarker(value)];\n}\n\nfunction osmAreaPayload(options: OsmAreaOptions): Record<string, unknown> {\n const hasBbox = options.bbox !== undefined;\n const hasCenterRadius =\n options.center !== undefined && options.radius !== undefined;\n if (hasBbox === hasCenterRadius) {\n throw new Error(\"Provide either --bbox or --center with --radius\");\n }\n return {\n ...(options.bbox ? { bbox: options.bbox } : {}),\n ...(options.center ? { center: options.center } : {}),\n ...(options.radius !== undefined ? { radiusMeters: options.radius } : {}),\n layers: options.layers,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction resultRecord(response: ZeroMapsResponse): Record<string, unknown> {\n if (!isRecord(response.result)) {\n throw new Error(\"Zero Maps response did not include an object result\");\n }\n return response.result;\n}\n\nfunction stringField(\n value: Record<string, unknown>,\n key: string,\n): string | undefined {\n const field = value[key];\n return typeof field === \"string\" ? field : undefined;\n}\n\nfunction numberField(\n value: Record<string, unknown>,\n key: string,\n): number | undefined {\n const field = value[key];\n return typeof field === \"number\" ? field : undefined;\n}\n\nasync function writeOutputFile(\n outputPath: string,\n content: string | Buffer,\n): Promise<void> {\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, content);\n}\n\nasync function writeOsmGeoJson(\n outputPath: string,\n response: ZeroMapsResponse,\n): Promise<void> {\n const result = resultRecord(response);\n if (!(\"geojson\" in result)) {\n throw new Error(\"Zero Maps OSM download response did not include geojson\");\n }\n await writeOutputFile(\n outputPath,\n `${JSON.stringify(result.geojson, null, 2)}\\n`,\n );\n}\n\nasync function writeOsmPng(\n outputPath: string,\n response: ZeroMapsResponse,\n): Promise<void> {\n const result = resultRecord(response);\n const image = result.image;\n if (!isRecord(image) || typeof image.base64 !== \"string\") {\n throw new Error(\n \"Zero Maps OSM render response did not include a PNG image\",\n );\n }\n await writeOutputFile(outputPath, Buffer.from(image.base64, \"base64\"));\n}\n\nfunction renderMapsMetadata(response: ZeroMapsResponse): void {\n if (response.provider) {\n console.log(chalk.dim(` Provider: ${response.provider}`));\n }\n if (response.billingCategory) {\n console.log(chalk.dim(` Billing category: ${response.billingCategory}`));\n }\n if (response.billingQuantity !== undefined) {\n console.log(chalk.dim(` Billing quantity: ${response.billingQuantity}`));\n }\n if (response.creditsCharged !== undefined) {\n console.log(chalk.dim(` Credits charged: ${response.creditsCharged}`));\n }\n}\n\nfunction renderMapsResponse(label: string, response: ZeroMapsResponse): void {\n console.log(chalk.green(`✓ ${label}`));\n renderMapsMetadata(response);\n\n const result = response.result ?? response;\n console.log(JSON.stringify(result, null, 2));\n}\n\nfunction renderOsmFileResponse(\n label: string,\n response: ZeroMapsResponse,\n outputPath: string,\n): void {\n console.log(chalk.green(`✓ ${label}`));\n renderMapsMetadata(response);\n\n const result = isRecord(response.result) ? response.result : {};\n const featureCount = numberField(result, \"featureCount\");\n const attribution = stringField(result, \"attribution\");\n if (featureCount !== undefined) {\n console.log(chalk.dim(` Features: ${featureCount}`));\n }\n if (attribution) {\n console.log(chalk.dim(` Attribution: ${attribution}`));\n }\n console.log(chalk.dim(` Output: ${outputPath}`));\n}\n\nasync function runMapsRequest(\n label: string,\n endpoint:\n | \"geocode\"\n | \"reverse-geocode\"\n | \"directions\"\n | \"places/search\"\n | \"places/details\"\n | \"osm/download\"\n | \"osm/render\",\n payload: Record<string, unknown>,\n options: JsonOption,\n): Promise<void> {\n const response = await callZeroMaps(endpoint, payload);\n\n if (options.json) {\n console.log(JSON.stringify(response));\n return;\n }\n\n renderMapsResponse(label, response);\n}\n\nconst geocodeCommand = new Command()\n .name(\"geocode\")\n .description(\"Convert an address into coordinates\")\n .requiredOption(\"--address <address>\", \"Address to geocode\")\n .option(\"--region <code>\", \"Optional region bias, such as US or CN\")\n .option(\"--json\", \"Print the raw maps response as JSON\")\n .action(\n withErrorHandler(async (options: GeocodeOptions) => {\n await runMapsRequest(\n \"Geocode completed\",\n \"geocode\",\n { address: options.address, region: options.region },\n options,\n );\n }),\n );\n\nconst reverseGeocodeCommand = new Command()\n .name(\"reverse-geocode\")\n .description(\"Convert coordinates into an address\")\n .requiredOption(\"--lat <number>\", \"Latitude\", parseLatitude)\n .requiredOption(\"--lng <number>\", \"Longitude\", parseLongitude)\n .option(\"--json\", \"Print the raw maps response as JSON\")\n .action(\n withErrorHandler(async (options: ReverseGeocodeOptions) => {\n await runMapsRequest(\n \"Reverse geocode completed\",\n \"reverse-geocode\",\n { lat: options.lat, lng: options.lng },\n options,\n );\n }),\n );\n\nconst directionsCommand = new Command()\n .name(\"directions\")\n .description(\"Get a route between two places\")\n .requiredOption(\n \"--origin <place>\",\n \"Origin address, coordinates, or place ID\",\n )\n .requiredOption(\n \"--destination <place>\",\n \"Destination address, coordinates, or place ID\",\n )\n .option(\n \"--mode <mode>\",\n \"Travel mode: driving, walking, bicycling, or transit\",\n parseTravelMode,\n \"driving\",\n )\n .option(\"--departure-time <time>\", \"ISO departure time or provider keyword\")\n .option(\"--json\", \"Print the raw maps response as JSON\")\n .action(\n withErrorHandler(async (options: DirectionsOptions) => {\n await runMapsRequest(\n \"Directions completed\",\n \"directions\",\n {\n origin: options.origin,\n destination: options.destination,\n mode: options.mode,\n departureTime: options.departureTime,\n },\n options,\n );\n }),\n );\n\nconst placesSearchCommand = new Command()\n .name(\"search\")\n .description(\"Search for places\")\n .requiredOption(\"--query <query>\", \"Place search query\")\n .option(\"--location <lat,lng>\", \"Optional location bias\")\n .option(\n \"--radius <meters>\",\n \"Optional search radius in meters\",\n parsePositiveInteger,\n )\n .option(\n \"--limit <n>\",\n \"Maximum places to return, from 1 to 20\",\n parseLimit,\n 5,\n )\n .option(\"--region <code>\", \"Optional region bias, such as US or CN\")\n .option(\n \"--fields <fields>\",\n \"Field set: pro or enterprise\",\n parsePlaceSearchFields,\n \"pro\",\n )\n .option(\"--json\", \"Print the raw maps response as JSON\")\n .action(\n withErrorHandler(async (options: PlacesSearchOptions) => {\n await runMapsRequest(\n \"Places search completed\",\n \"places/search\",\n {\n query: options.query,\n location: options.location,\n radius: options.radius,\n limit: options.limit,\n region: options.region,\n fields: options.fields,\n },\n options,\n );\n }),\n );\n\nconst placesDetailsCommand = new Command()\n .name(\"details\")\n .description(\"Get details for a place\")\n .requiredOption(\"--place-id <id>\", \"Provider place ID\")\n .option(\n \"--fields <fields>\",\n \"Field set: essentials, pro, or enterprise\",\n parsePlaceDetailFields,\n \"essentials\",\n )\n .option(\"--json\", \"Print the raw maps response as JSON\")\n .action(\n withErrorHandler(async (options: PlacesDetailsOptions) => {\n await runMapsRequest(\n \"Place details completed\",\n \"places/details\",\n { placeId: options.placeId, fields: options.fields },\n options,\n );\n }),\n );\n\nconst osmDownloadCommand = new Command()\n .name(\"download\")\n .description(\"Download OpenStreetMap vector features as GeoJSON\")\n .option(\n \"--bbox <west,south,east,north>\",\n \"Bounding box in WGS84 coordinates\",\n parseBBox,\n )\n .option(\n \"--center <lat,lng>\",\n \"Center point in WGS84 coordinates\",\n parseLatLng,\n )\n .option(\n \"--radius <meters>\",\n \"Radius in meters when using --center\",\n parsePositiveInteger,\n )\n .option(\n \"--layers <layers>\",\n \"Comma-separated layers: roads, buildings, water, parks\",\n parseOsmLayers,\n OSM_LAYERS,\n )\n .option(\"--output <path>\", \"Write GeoJSON to a file\")\n .option(\"--json\", \"Print the raw maps response as JSON\")\n .action(\n withErrorHandler(async (options: OsmAreaOptions) => {\n const response = await callZeroMaps(\n \"osm/download\",\n osmAreaPayload(options),\n );\n if (options.output) {\n await writeOsmGeoJson(options.output, response);\n }\n if (options.json) {\n console.log(JSON.stringify(response));\n return;\n }\n if (options.output) {\n renderOsmFileResponse(\n \"OSM download completed\",\n response,\n options.output,\n );\n return;\n }\n renderMapsResponse(\"OSM download completed\", response);\n }),\n );\n\nconst osmRenderCommand = new Command()\n .name(\"render\")\n .description(\"Render OpenStreetMap vector features to PNG\")\n .option(\n \"--bbox <west,south,east,north>\",\n \"Bounding box in WGS84 coordinates\",\n parseBBox,\n )\n .option(\n \"--center <lat,lng>\",\n \"Center point in WGS84 coordinates\",\n parseLatLng,\n )\n .option(\n \"--radius <meters>\",\n \"Radius in meters when using --center\",\n parsePositiveInteger,\n )\n .option(\n \"--layers <layers>\",\n \"Comma-separated layers: roads, buildings, water, parks\",\n parseOsmLayers,\n OSM_LAYERS,\n )\n .option(\n \"--width <px>\",\n \"PNG width in pixels, from 320 to 2048\",\n (value) => {\n return parseIntegerInRange(value, 320, 2_048);\n },\n 1_536,\n )\n .option(\n \"--height <px>\",\n \"PNG height in pixels, from 240 to 2048\",\n (value) => {\n return parseIntegerInRange(value, 240, 2_048);\n },\n 1_024,\n )\n .option(\n \"--style <style>\",\n \"Render style: standard or guide\",\n parseOsmStyle,\n \"standard\",\n )\n .option(\"--title <text>\", \"Optional title drawn onto the PNG\")\n .option(\n \"--marker <lat,lng[,label]>\",\n \"Marker to draw; repeat for multiple markers\",\n collectOsmMarker,\n [],\n )\n .requiredOption(\"--output <path>\", \"Write PNG to a file\")\n .option(\"--json\", \"Print the raw maps response as JSON\")\n .action(\n withErrorHandler(async (options: OsmRenderOptions) => {\n const response = await callZeroMaps(\"osm/render\", {\n ...osmAreaPayload(options),\n width: options.width,\n height: options.height,\n style: options.style,\n title: options.title,\n markers: options.marker,\n });\n await writeOsmPng(options.output, response);\n if (options.json) {\n console.log(JSON.stringify(response));\n return;\n }\n renderOsmFileResponse(\"OSM render completed\", response, options.output);\n }),\n );\n\nconst osmCommand = new Command()\n .name(\"osm\")\n .description(\"Download and render OpenStreetMap data\")\n .addCommand(osmDownloadCommand)\n .addCommand(osmRenderCommand);\n\nconst placesCommand = new Command()\n .name(\"places\")\n .description(\"Search places and fetch place details\")\n .addCommand(placesSearchCommand)\n .addCommand(placesDetailsCommand);\n\nexport const zeroMapsCommand = new Command()\n .name(\"maps\")\n .description(\"Use managed zero maps services\")\n .addCommand(geocodeCommand)\n .addCommand(reverseGeocodeCommand)\n .addCommand(directionsCommand)\n .addCommand(placesCommand)\n .addCommand(osmCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n Geocode address: zero maps geocode --address \"1 Infinite Loop, Cupertino\" --json\n Get route: zero maps directions --origin \"SFO\" --destination \"Mountain View\" --mode driving --json\n Search places: zero maps places search --query \"coffee near Union Square SF\" --limit 5 --json\n Enterprise search: zero maps places search --query \"restaurants in SoMa\" --fields enterprise --json\n Place details: zero maps places details --place-id <id> --fields essentials --json\n Enterprise details: zero maps places details --place-id <id> --fields enterprise --json\n Download OSM data: zero maps osm download --bbox -122.43,37.76,-122.40,37.79 --output map.geojson\n Render OSM PNG: zero maps osm render --center 37.7749,-122.4194 --radius 1200 --output map.png\n\nNotes:\n - Authenticates via ZERO_TOKEN (requires maps:read capability) or a CLI token\n - Google Maps and OpenStreetMap calls and credit billing happen on the vm0 API server\n - Use --fields essentials for place details unless paid fields are required`,\n );\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/zero/model/index.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { getVm0ModelPriceTier } from \"@vm0/api-contracts/contracts/model-providers\";\nimport { listZeroModelPolicies } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\nimport {\n formatModelPolicyStatus,\n formatModelProviderRoute,\n getModelProviderRouteKind,\n} from \"../../../lib/domain/model-policy-display\";\n\nfunction formatPriceTier(tier: string | undefined): string {\n return tier ?? \"unknown\";\n}\n\nfunction getCurrentIntegration(): string | null {\n const prompt = process.env.VM0_APPEND_SYSTEM_PROMPT;\n if (!prompt) {\n return null;\n }\n\n const match = prompt.match(/You are currently running inside:\\s*([^\\n]+)/i);\n return match?.[1]?.trim().toLowerCase() ?? null;\n}\n\nexport function getModelSwitchGuidance(integration = getCurrentIntegration()) {\n const normalizedIntegration = integration?.toLowerCase();\n\n if (normalizedIntegration === \"web\") {\n return \"Switch models from the model selector next to the input box in the web chat.\";\n }\n\n if (normalizedIntegration === \"telegram\") {\n return \"Use /model in Telegram to switch models.\";\n }\n\n return \"Open https://app.vm0.ai and switch models from the model selector next to the input box.\";\n}\n\nconst listCommand = new Command()\n .name(\"list\")\n .alias(\"ls\")\n .description(\"List models allowed by the current organization\")\n .action(\n withErrorHandler(async () => {\n const result = await listZeroModelPolicies();\n\n if (result.policies.length === 0) {\n console.log(chalk.dim(\"No models are allowed for this organization\"));\n return;\n }\n\n console.log(chalk.bold(\"Allowed Models:\"));\n console.log();\n\n for (const policy of result.policies) {\n const defaultMarker = policy.isDefault ? chalk.dim(\" (default)\") : \"\";\n console.log(\n ` - ${policy.modelLabel} ${chalk.dim(`(${policy.model})`)}${defaultMarker}`,\n );\n console.log(` provider: ${formatModelProviderRoute(policy)}`);\n\n if (getModelProviderRouteKind(policy) === \"built-in\") {\n console.log(\n ` price tier: ${formatPriceTier(getVm0ModelPriceTier(policy.model))}`,\n );\n }\n\n const status = formatModelPolicyStatus(policy);\n if (status) {\n console.log(chalk.yellow(` status: ${status}`));\n }\n }\n\n console.log();\n console.log(\n chalk.dim(\n \"Use `zero model-provider set --help` to see how to switch each model between built-in and BYOK.\",\n ),\n );\n }),\n );\n\nexport const switchCommand = new Command()\n .name(\"switch\")\n .description(\"Show how to switch models in the current environment\")\n .action(() => {\n console.log(getModelSwitchGuidance());\n });\n\nexport const zeroModelCommand = new Command()\n .name(\"model\")\n .description(\"List available models and model-switching guidance\")\n .addCommand(listCommand)\n .addCommand(switchCommand);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAWA,SAAS,gBAAgB,MAAkC;AACzD,SAAO,QAAQ;AACjB;AAEA,SAAS,wBAAuC;AAC9C,QAAM,SAAS,QAAQ,IAAI;AAC3B,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,OAAO,MAAM,+CAA+C;AAC1E,SAAO,QAAQ,CAAC,GAAG,KAAK,EAAE,YAAY,KAAK;AAC7C;AAEO,SAAS,uBAAuB,cAAc,sBAAsB,GAAG;AAC5E,QAAM,wBAAwB,aAAa,YAAY;AAEvD,MAAI,0BAA0B,OAAO;AACnC,WAAO;AAAA,EACT;AAEA,MAAI,0BAA0B,YAAY;AACxC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,IAAM,cAAc,IAAI,QAAQ,EAC7B,KAAK,MAAM,EACX,MAAM,IAAI,EACV,YAAY,iDAAiD,EAC7D;AAAA,EACC,iBAAiB,YAAY;AAC3B,UAAM,SAAS,MAAM,sBAAsB;AAE3C,QAAI,OAAO,SAAS,WAAW,GAAG;AAChC,cAAQ,IAAI,eAAM,IAAI,6CAA6C,CAAC;AACpE;AAAA,IACF;AAEA,YAAQ,IAAI,eAAM,KAAK,iBAAiB,CAAC;AACzC,YAAQ,IAAI;AAEZ,eAAW,UAAU,OAAO,UAAU;AACpC,YAAM,gBAAgB,OAAO,YAAY,eAAM,IAAI,YAAY,IAAI;AACnE,cAAQ;AAAA,QACN,OAAO,OAAO,UAAU,IAAI,eAAM,IAAI,IAAI,OAAO,KAAK,GAAG,CAAC,GAAG,aAAa;AAAA,MAC5E;AACA,cAAQ,IAAI,iBAAiB,yBAAyB,MAAM,CAAC,EAAE;AAE/D,UAAI,0BAA0B,MAAM,MAAM,YAAY;AACpD,gBAAQ;AAAA,UACN,mBAAmB,gBAAgB,qBAAqB,OAAO,KAAK,CAAC,CAAC;AAAA,QACxE;AAAA,MACF;AAEA,YAAM,SAAS,wBAAwB,MAAM;AAC7C,UAAI,QAAQ;AACV,gBAAQ,IAAI,eAAM,OAAO,eAAe,MAAM,EAAE,CAAC;AAAA,MACnD;AAAA,IACF;AAEA,YAAQ,IAAI;AACZ,YAAQ;AAAA,MACN,eAAM;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEK,IAAM,gBAAgB,IAAI,QAAQ,EACtC,KAAK,QAAQ,EACb,YAAY,sDAAsD,EAClE,OAAO,MAAM;AACZ,UAAQ,IAAI,uBAAuB,CAAC;AACtC,CAAC;AAEI,IAAM,mBAAmB,IAAI,QAAQ,EACzC,KAAK,OAAO,EACZ,YAAY,oDAAoD,EAChE,WAAW,WAAW,EACtB,WAAW,aAAa;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/zero/model-provider/index.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { listZeroModelPolicies } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\nimport {\n formatModelPolicyStatus,\n getModelProviderRouteKind,\n getModelProviderTypeLabel,\n} from \"../../../lib/domain/model-policy-display\";\n\nexport const MODEL_PROVIDER_SET_GUIDANCE = [\n \"Model provider routing is configured in the web app.\",\n \"\",\n \"Organization admins: open https://app.vm0.ai, use the top-left organization menu, choose Manage, then add, delete, or adjust model providers.\",\n \"\",\n \"If an organization admin sets a model provider to subscription, members must use the bottom-left user menu, choose Preferences / Personal Models, and connect their personal subscription.\",\n].join(\"\\n\");\n\nconst listCommand = new Command()\n .name(\"list\")\n .alias(\"ls\")\n .description(\n \"List provider routing for each model allowed by the organization\",\n )\n .action(\n withErrorHandler(async () => {\n const result = await listZeroModelPolicies();\n\n if (result.policies.length === 0) {\n console.log(\n chalk.dim(\n \"No model provider routes are allowed for this organization\",\n ),\n );\n return;\n }\n\n console.log(chalk.bold(\"Model Provider Routes:\"));\n console.log();\n\n for (const policy of result.policies) {\n const defaultMarker = policy.isDefault ? chalk.dim(\" (default)\") : \"\";\n console.log(\n ` - ${policy.modelLabel} ${chalk.dim(`(${policy.model})`)}${defaultMarker}`,\n );\n console.log(` provider: ${getModelProviderRouteKind(policy)}`);\n console.log(\n ` provider type: ${policy.defaultProviderType} (${getModelProviderTypeLabel(policy.defaultProviderType)})`,\n );\n\n const status = formatModelPolicyStatus(policy);\n if (status) {\n console.log(chalk.yellow(` status: ${status}`));\n }\n }\n }),\n );\n\nexport const setCommand = new Command()\n .name(\"set\")\n .description(\"Show where to adjust model provider routing\")\n .addHelpText(\"after\", `\\n${MODEL_PROVIDER_SET_GUIDANCE}`)\n .action(() => {\n console.log(MODEL_PROVIDER_SET_GUIDANCE);\n });\n\nexport const zeroModelProviderCommand = new Command()\n .name(\"model-provider\")\n .description(\"Inspect model provider routing\")\n .addCommand(listCommand)\n .addCommand(setCommand);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAUO,IAAM,8BAA8B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAEX,IAAM,cAAc,IAAI,QAAQ,EAC7B,KAAK,MAAM,EACX,MAAM,IAAI,EACV;AAAA,EACC;AACF,EACC;AAAA,EACC,iBAAiB,YAAY;AAC3B,UAAM,SAAS,MAAM,sBAAsB;AAE3C,QAAI,OAAO,SAAS,WAAW,GAAG;AAChC,cAAQ;AAAA,QACN,eAAM;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAEA,YAAQ,IAAI,eAAM,KAAK,wBAAwB,CAAC;AAChD,YAAQ,IAAI;AAEZ,eAAW,UAAU,OAAO,UAAU;AACpC,YAAM,gBAAgB,OAAO,YAAY,eAAM,IAAI,YAAY,IAAI;AACnE,cAAQ;AAAA,QACN,OAAO,OAAO,UAAU,IAAI,eAAM,IAAI,IAAI,OAAO,KAAK,GAAG,CAAC,GAAG,aAAa;AAAA,MAC5E;AACA,cAAQ,IAAI,iBAAiB,0BAA0B,MAAM,CAAC,EAAE;AAChE,cAAQ;AAAA,QACN,sBAAsB,OAAO,mBAAmB,KAAK,0BAA0B,OAAO,mBAAmB,CAAC;AAAA,MAC5G;AAEA,YAAM,SAAS,wBAAwB,MAAM;AAC7C,UAAI,QAAQ;AACV,gBAAQ,IAAI,eAAM,OAAO,eAAe,MAAM,EAAE,CAAC;AAAA,MACnD;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEK,IAAM,aAAa,IAAI,QAAQ,EACnC,KAAK,KAAK,EACV,YAAY,6CAA6C,EACzD,YAAY,SAAS;AAAA,EAAK,2BAA2B,EAAE,EACvD,OAAO,MAAM;AACZ,UAAQ,IAAI,2BAA2B;AACzC,CAAC;AAEI,IAAM,2BAA2B,IAAI,QAAQ,EACjD,KAAK,gBAAgB,EACrB,YAAY,gCAAgC,EAC5C,WAAW,WAAW,EACtB,WAAW,UAAU;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/zero/people-search/index.ts"],"sourcesContent":["import {\n ZERO_PEOPLE_SEARCH_DEFAULT_LIMIT,\n ZERO_PEOPLE_SEARCH_MAX_LIMIT,\n zeroPeopleSearchRequestSchema,\n} from \"@vm0/api-contracts/contracts/zero-people-search\";\nimport chalk from \"chalk\";\nimport { Command, InvalidArgumentError, Option } from \"commander\";\n\nimport {\n callZeroPeopleSearch,\n type ZeroPeopleSearchResponse,\n} from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\ninterface PeopleSearchOptions {\n readonly limit: number;\n readonly json?: boolean;\n}\n\nfunction parseLimit(value: string): number {\n if (!/^\\d+$/.test(value)) {\n throw new InvalidArgumentError(\n `limit must be an integer from 1 to ${ZERO_PEOPLE_SEARCH_MAX_LIMIT}`,\n );\n }\n const limit = Number(value);\n if (limit < 1 || limit > ZERO_PEOPLE_SEARCH_MAX_LIMIT) {\n throw new InvalidArgumentError(\n `limit must be an integer from 1 to ${ZERO_PEOPLE_SEARCH_MAX_LIMIT}`,\n );\n }\n return limit;\n}\n\nfunction renderMetadata(response: ZeroPeopleSearchResponse): void {\n console.log(chalk.dim(` Provider: ${response.provider}`));\n console.log(chalk.dim(` Billing category: ${response.billingCategory}`));\n console.log(chalk.dim(` Billing quantity: ${response.billingQuantity}`));\n console.log(chalk.dim(` Credits charged: ${response.creditsCharged}`));\n}\n\nfunction renderProfile(\n profile: ZeroPeopleSearchResponse[\"profiles\"][number],\n index: number,\n): void {\n console.log(`${index + 1}. ${profile.name}`);\n if (profile.title) {\n console.log(` Title: ${profile.title}`);\n }\n if (profile.company) {\n console.log(` Company: ${profile.company}`);\n }\n if (profile.location) {\n console.log(` Location: ${profile.location}`);\n }\n if (profile.summary) {\n console.log(` ${profile.summary}`);\n }\n console.log(\" Sources:\");\n for (const [sourceIndex, source] of profile.sources.entries()) {\n console.log(\n ` ${sourceIndex + 1}. ${source.title || \"(untitled source)\"}`,\n );\n console.log(` ${source.url}`);\n }\n}\n\nfunction renderProfiles(response: ZeroPeopleSearchResponse): void {\n if (response.profiles.length === 0) {\n console.log(\n chalk.dim(\n \"No matching professionals found. Try a broader role, company, skill, or location query.\",\n ),\n );\n return;\n }\n for (const [index, profile] of response.profiles.entries()) {\n renderProfile(profile, index);\n }\n}\n\nexport const zeroPeopleSearchCommand = new Command()\n .name(\"people-search\")\n .description(\"Find professionals through managed zero people search\")\n .argument(\"<query>\", \"Professional research query\")\n .addOption(\n new Option(\n \"--limit <count>\",\n `Maximum profiles (1-${ZERO_PEOPLE_SEARCH_MAX_LIMIT})`,\n )\n .default(ZERO_PEOPLE_SEARCH_DEFAULT_LIMIT)\n .argParser(parseLimit),\n )\n .option(\"--json\", \"Print the raw people-search response as JSON\")\n .action(\n withErrorHandler(async (query: string, options: PeopleSearchOptions) => {\n const request = zeroPeopleSearchRequestSchema.safeParse({\n query,\n limit: options.limit,\n });\n if (!request.success) {\n throw new InvalidArgumentError(\n request.error.issues[0]?.message ??\n \"people-search request is invalid\",\n );\n }\n const response = await callZeroPeopleSearch(request.data);\n if (options.json) {\n console.log(JSON.stringify(response));\n return;\n }\n console.log(chalk.green(\"✓ People search completed\"));\n renderMetadata(response);\n renderProfiles(response);\n }),\n )\n .addHelpText(\n \"after\",\n `\nExamples:\n Find a professional: zero people-search \"Who leads platform engineering at Notion?\"\n Search by criteria: zero people-search \"Fintech compliance leaders in New York\" --limit 10\n Machine-readable: zero people-search \"Kubernetes platform engineers\" --json\n\nNotes:\n - Authenticates via ZERO_TOKEN (requires people-search:read capability) or a CLI token\n - Successful requests use managed credits, including searches with no matches\n - Queries are sent to vm0's managed Perplexity provider; never include secrets or private context\n - Profile fields are model-extracted from public professional sources and are not verified facts\n - Verify important claims using the provider-backed source URLs shown with each profile\n - Use only for legitimate professional research; never for harassment, doxxing, stalking, unauthorized background screening, or unlawful employment/privacy decisions\n - This command does not enrich email/phone data, message people, scrape profiles, or access authenticated LinkedIn`,\n );\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAmBA,SAAS,WAAW,OAAuB;AACzC,MAAI,CAAC,QAAQ,KAAK,KAAK,GAAG;AACxB,UAAM,IAAI;AAAA,MACR,sCAAsC,4BAA4B;AAAA,IACpE;AAAA,EACF;AACA,QAAM,QAAQ,OAAO,KAAK;AAC1B,MAAI,QAAQ,KAAK,QAAQ,8BAA8B;AACrD,UAAM,IAAI;AAAA,MACR,sCAAsC,4BAA4B;AAAA,IACpE;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,eAAe,UAA0C;AAChE,UAAQ,IAAI,eAAM,IAAI,eAAe,SAAS,QAAQ,EAAE,CAAC;AACzD,UAAQ,IAAI,eAAM,IAAI,uBAAuB,SAAS,eAAe,EAAE,CAAC;AACxE,UAAQ,IAAI,eAAM,IAAI,uBAAuB,SAAS,eAAe,EAAE,CAAC;AACxE,UAAQ,IAAI,eAAM,IAAI,sBAAsB,SAAS,cAAc,EAAE,CAAC;AACxE;AAEA,SAAS,cACP,SACA,OACM;AACN,UAAQ,IAAI,GAAG,QAAQ,CAAC,KAAK,QAAQ,IAAI,EAAE;AAC3C,MAAI,QAAQ,OAAO;AACjB,YAAQ,IAAI,aAAa,QAAQ,KAAK,EAAE;AAAA,EAC1C;AACA,MAAI,QAAQ,SAAS;AACnB,YAAQ,IAAI,eAAe,QAAQ,OAAO,EAAE;AAAA,EAC9C;AACA,MAAI,QAAQ,UAAU;AACpB,YAAQ,IAAI,gBAAgB,QAAQ,QAAQ,EAAE;AAAA,EAChD;AACA,MAAI,QAAQ,SAAS;AACnB,YAAQ,IAAI,MAAM,QAAQ,OAAO,EAAE;AAAA,EACrC;AACA,UAAQ,IAAI,aAAa;AACzB,aAAW,CAAC,aAAa,MAAM,KAAK,QAAQ,QAAQ,QAAQ,GAAG;AAC7D,YAAQ;AAAA,MACN,QAAQ,cAAc,CAAC,KAAK,OAAO,SAAS,mBAAmB;AAAA,IACjE;AACA,YAAQ,IAAI,WAAW,OAAO,GAAG,EAAE;AAAA,EACrC;AACF;AAEA,SAAS,eAAe,UAA0C;AAChE,MAAI,SAAS,SAAS,WAAW,GAAG;AAClC,YAAQ;AAAA,MACN,eAAM;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AACA;AAAA,EACF;AACA,aAAW,CAAC,OAAO,OAAO,KAAK,SAAS,SAAS,QAAQ,GAAG;AAC1D,kBAAc,SAAS,KAAK;AAAA,EAC9B;AACF;AAEO,IAAM,0BAA0B,IAAI,QAAQ,EAChD,KAAK,eAAe,EACpB,YAAY,uDAAuD,EACnE,SAAS,WAAW,6BAA6B,EACjD;AAAA,EACC,IAAI;AAAA,IACF;AAAA,IACA,uBAAuB,4BAA4B;AAAA,EACrD,EACG,QAAQ,gCAAgC,EACxC,UAAU,UAAU;AACzB,EACC,OAAO,UAAU,8CAA8C,EAC/D;AAAA,EACC,iBAAiB,OAAO,OAAe,YAAiC;AACtE,UAAM,UAAU,8BAA8B,UAAU;AAAA,MACtD;AAAA,MACA,OAAO,QAAQ;AAAA,IACjB,CAAC;AACD,QAAI,CAAC,QAAQ,SAAS;AACpB,YAAM,IAAI;AAAA,QACR,QAAQ,MAAM,OAAO,CAAC,GAAG,WACvB;AAAA,MACJ;AAAA,IACF;AACA,UAAM,WAAW,MAAM,qBAAqB,QAAQ,IAAI;AACxD,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,KAAK,UAAU,QAAQ,CAAC;AACpC;AAAA,IACF;AACA,YAAQ,IAAI,eAAM,MAAM,gCAA2B,CAAC;AACpD,mBAAe,QAAQ;AACvB,mBAAe,QAAQ;AAAA,EACzB,CAAC;AACH,EACC;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/zero/phone/index.ts","../src/commands/zero/phone/download-file.ts","../src/commands/zero/phone/message.ts","../src/commands/zero/phone/upload-file.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { downloadFileCommand } from \"./download-file\";\nimport { messageCommand } from \"./message\";\nimport { uploadFileCommand } from \"./upload-file\";\n\nexport const zeroPhoneCommand = new Command()\n .name(\"phone\")\n .description(\"Send AgentPhone messages, upload files, and download media\")\n .addCommand(messageCommand)\n .addCommand(downloadFileCommand)\n .addCommand(uploadFileCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n Send a message: zero phone message --to +15551234567 -t \"Hello!\"\n Upload a file: zero phone upload-file -f /tmp/report.pdf --to +15551234567\n Download a file: zero phone download-file <file-id> -o /tmp/out.jpg`,\n );\n","import { basename, join } from \"path\";\nimport { tmpdir } from \"os\";\nimport { Command } from \"commander\";\nimport { downloadPhoneFile } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nfunction defaultOutPath(fileId: string): string {\n return join(tmpdir(), `phone-${basename(fileId)}`);\n}\n\nexport const downloadFileCommand = new Command()\n .name(\"download-file\")\n .description(\"Download an AgentPhone media file by id\")\n .argument(\n \"<file-id>\",\n \"AgentPhone message id from an [AgentPhone file] block\",\n )\n .option(\n \"-o, --out <path>\",\n \"Output path for the downloaded file (default: /tmp/phone-<file-id>)\",\n )\n .addHelpText(\n \"after\",\n `\nExamples:\n Download to default temp path: zero phone download-file msg_123\n Download to explicit path: zero phone download-file msg_123 -o /tmp/photo.jpg\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"path\":\"/tmp/phone-msg_123\",\"mimetype\":\"image/jpeg\",\"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/<file-id>_frame_%03d.jpg\n - PDF/text/csv/json/markdown: read the file directly`,\n )\n .action(\n withErrorHandler(async (fileId: string, options: { out?: string }) => {\n const outPath = options.out ?? defaultOutPath(fileId);\n const result = await downloadPhoneFile(fileId, outPath);\n console.log(JSON.stringify(result));\n }),\n );\n","import { readFileSync } from \"fs\";\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { sendPhoneMessage } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nexport const messageCommand = new Command()\n .name(\"message\")\n .description(\"Send an AgentPhone text message\")\n .requiredOption(\"--to <phone>\", \"Connected phone handle to message\")\n .option(\"--agent-id <id>\", \"AgentPhone agent ID (inferred when omitted)\")\n .option(\"-t, --text <message>\", \"Message text\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Send a message: zero phone message --to +15551234567 -t \"Hello!\"\n From stdin: printf \"Hello!\" | zero phone message --to +15551234567\n\nNotes:\n - The phone handle must already be connected to the authenticated VM0 user\n - AgentPhone agent ID is inferred from the conversation when omitted`,\n )\n .action(\n withErrorHandler(\n async (options: { to: string; agentId?: string; text?: string }) => {\n let text = options.text;\n if (!text && !process.stdin.isTTY) {\n try {\n text = readFileSync(\"/dev/stdin\", \"utf8\").trim();\n } catch {\n // stdin not readable (e.g. test runner with no piped input);\n // fall through to the missing-text validation below.\n }\n }\n\n if (!text) {\n throw new Error(\"Either --text or piped stdin must be provided\", {\n cause: new Error(\n 'Usage: zero phone message --to +15551234567 -t \"your message\"',\n ),\n });\n }\n\n const result = await sendPhoneMessage({\n toNumber: options.to,\n text,\n agentphoneAgentId: options.agentId,\n });\n\n console.log(\n chalk.green(`✓ Message sent (message_id: ${result.messageId})`),\n );\n },\n ),\n );\n","import { readFileSync, statSync } from \"fs\";\nimport { basename, extname } from \"path\";\nimport { Command } from \"commander\";\nimport { completePhoneFileUpload, initPhoneFileUpload } 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\nexport const uploadFileCommand = new Command()\n .name(\"upload-file\")\n .description(\"Upload a local file to an AgentPhone conversation\")\n .requiredOption(\"-f, --file <path>\", \"Local file path to upload\")\n .requiredOption(\"--to <phone>\", \"Connected phone handle to message\")\n .option(\"--agent-id <id>\", \"AgentPhone agent ID (inferred when omitted)\")\n .option(\"--caption <text>\", \"Caption to accompany the file\")\n .option(\"--content-type <mime>\", \"Override inferred content type\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Upload a file: zero phone upload-file -f /tmp/report.pdf --to +15551234567\n With a caption: zero phone upload-file -f /tmp/photo.jpg --to +15551234567 --caption \"Here it is\"\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"messageId\":\"msg_123\",\"toNumber\":\"+15551234567\",\"filename\":\"report.pdf\",\"mimetype\":\"application/pdf\",\"size\":12345,\"url\":\"https://...\"}`,\n )\n .action(\n withErrorHandler(\n async (options: {\n file: string;\n to: string;\n agentId?: 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\n const prepared = await initPhoneFileUpload({\n filename,\n contentType,\n length: fileSize,\n supportsUploadHeaders: true,\n });\n\n const fileContent = readFileSync(options.file);\n const uploadResponse = await fetch(prepared.uploadUrl, {\n method: \"PUT\",\n headers: {\n \"Content-Type\": prepared.contentType,\n ...prepared.uploadHeaders,\n },\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 completePhoneFileUpload({\n uploadId: prepared.uploadId,\n toNumber: options.to,\n agentphoneAgentId: options.agentId,\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":["readFileSync","basename","basename","readFileSync"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/zero/recognize/index.ts"],"sourcesContent":["import { statSync } from \"node:fs\";\n\nimport {\n ZERO_RECOGNITION_MAX_FILE_BYTES,\n ZERO_RECOGNITION_MAX_PROMPT_CHARS,\n zeroRecognitionImageMimeTypeSchema,\n type ZeroRecognitionImageMimeType,\n} from \"@vm0/api-contracts/contracts/zero-recognition\";\nimport { Command } from \"commander\";\n\nimport {\n ApiRequestError,\n callZeroRecognition,\n inferWebUploadContentType,\n uploadWebFile,\n} from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\ninterface RecognizeOptions {\n readonly file: string;\n readonly prompt: string;\n}\n\nfunction validatePrompt(prompt: string): string {\n const trimmed = prompt.trim();\n if (!trimmed) {\n throw new ApiRequestError(\n \"Recognition prompt must not be empty\",\n \"BAD_REQUEST\",\n 400,\n );\n }\n if (trimmed.length > ZERO_RECOGNITION_MAX_PROMPT_CHARS) {\n throw new ApiRequestError(\n `Recognition prompt must be ${ZERO_RECOGNITION_MAX_PROMPT_CHARS} characters or fewer`,\n \"BAD_REQUEST\",\n 400,\n );\n }\n return trimmed;\n}\n\nfunction validateImageFile(file: string): ZeroRecognitionImageMimeType {\n const stats = statSync(file);\n if (!stats.isFile()) {\n throw new ApiRequestError(\n `Not a regular file: ${file}`,\n \"BAD_REQUEST\",\n 400,\n );\n }\n if (stats.size === 0) {\n throw new ApiRequestError(\n \"Image file must not be empty\",\n \"BAD_REQUEST\",\n 400,\n );\n }\n if (stats.size > ZERO_RECOGNITION_MAX_FILE_BYTES) {\n throw new ApiRequestError(\n \"Image file must be 20 MB or smaller\",\n \"PAYLOAD_TOO_LARGE\",\n 413,\n );\n }\n\n const contentType = inferWebUploadContentType(file);\n const parsed = zeroRecognitionImageMimeTypeSchema.safeParse(contentType);\n if (!parsed.success) {\n throw new ApiRequestError(\n \"Image must be a PNG, JPEG, or WebP file\",\n \"BAD_REQUEST\",\n 400,\n );\n }\n return parsed.data;\n}\n\nexport const zeroRecognizeCommand = new Command()\n .name(\"recognize\")\n .description(\"Recognize one image through a managed multimodal model\")\n .requiredOption(\"-f, --file <path>\", \"Local PNG, JPEG, or WebP image\")\n .requiredOption(\"-p, --prompt <instruction>\", \"Recognition instruction\")\n .action(\n withErrorHandler(async (options: RecognizeOptions) => {\n const prompt = validatePrompt(options.prompt);\n const contentType = validateImageFile(options.file);\n const uploaded = await uploadWebFile(options.file, { contentType });\n const response = await callZeroRecognition({\n fileId: uploaded.id,\n prompt,\n });\n console.log(response.text);\n }),\n )\n .addHelpText(\n \"after\",\n `\nExample:\n zero recognize --file ./screenshot.png --prompt \"Describe the error shown\"\n\nNotes:\n - Available only in runs whose selected model does not support image input\n - Accepts one PNG, JPEG, or WebP image up to 20 MB\n - Uses a fixed vm0-managed recognition model and prints only recognized text`,\n );\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,SAAS,gBAAgB;AAuBzB,SAAS,eAAe,QAAwB;AAC9C,QAAM,UAAU,OAAO,KAAK;AAC5B,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,QAAQ,SAAS,mCAAmC;AACtD,UAAM,IAAI;AAAA,MACR,8BAA8B,iCAAiC;AAAA,MAC/D;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,MAA4C;AACrE,QAAM,QAAQ,SAAS,IAAI;AAC3B,MAAI,CAAC,MAAM,OAAO,GAAG;AACnB,UAAM,IAAI;AAAA,MACR,uBAAuB,IAAI;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,MAAM,OAAO,iCAAiC;AAChD,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,cAAc,0BAA0B,IAAI;AAClD,QAAM,SAAS,mCAAmC,UAAU,WAAW;AACvE,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO,OAAO;AAChB;AAEO,IAAM,uBAAuB,IAAI,QAAQ,EAC7C,KAAK,WAAW,EAChB,YAAY,wDAAwD,EACpE,eAAe,qBAAqB,gCAAgC,EACpE,eAAe,8BAA8B,yBAAyB,EACtE;AAAA,EACC,iBAAiB,OAAO,YAA8B;AACpD,UAAM,SAAS,eAAe,QAAQ,MAAM;AAC5C,UAAM,cAAc,kBAAkB,QAAQ,IAAI;AAClD,UAAM,WAAW,MAAM,cAAc,QAAQ,MAAM,EAAE,YAAY,CAAC;AAClE,UAAM,WAAW,MAAM,oBAAoB;AAAA,MACzC,QAAQ,SAAS;AAAA,MACjB;AAAA,IACF,CAAC;AACD,YAAQ,IAAI,SAAS,IAAI;AAAA,EAC3B,CAAC;AACH,EACC;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQF;","names":[]}