@vm0/cli 9.208.2 → 9.209.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 (58) hide show
  1. package/{chunk-VTG7YKGH.js → chunk-E4QFFTUC.js} +81 -6
  2. package/{chunk-VTG7YKGH.js.map → chunk-E4QFFTUC.js.map} +1 -1
  3. package/{chunk-NUMM3WMG.js → chunk-S3DAXIKY.js} +1 -1
  4. package/{chunk-NUMM3WMG.js.map → chunk-S3DAXIKY.js.map} +1 -1
  5. package/{clerk.generated-ZX6FS3MY.js → clerk.generated-VYPZORXB.js} +1 -1
  6. package/clerk.generated-VYPZORXB.js.map +1 -0
  7. package/{cloudflare.generated-6N4KWRE3.js → cloudflare.generated-YPGW4ALF.js} +1 -1
  8. package/cloudflare.generated-YPGW4ALF.js.map +1 -0
  9. package/{firewall-placeholder-expansion-FRPU64H3.js → firewall-placeholder-expansion-NK7UHGTN.js} +2 -2
  10. package/{gmail.generated-PL3HVAVP.js → gmail.generated-CXXGCZPP.js} +1 -1
  11. package/gmail.generated-CXXGCZPP.js.map +1 -0
  12. package/{google-analytics.generated-7EAP74EC.js → google-analytics.generated-LR5RC6K5.js} +1 -1
  13. package/google-analytics.generated-LR5RC6K5.js.map +1 -0
  14. package/{google-calendar.generated-66JO7MZH.js → google-calendar.generated-D4GJ7VO5.js} +1 -1
  15. package/google-calendar.generated-D4GJ7VO5.js.map +1 -0
  16. package/{google-cloud.generated-H4E5WNYB.js → google-cloud.generated-753VHV7L.js} +1 -1
  17. package/google-cloud.generated-753VHV7L.js.map +1 -0
  18. package/{google-docs.generated-NZYWOUOC.js → google-docs.generated-XH5A5CNI.js} +1 -1
  19. package/google-docs.generated-XH5A5CNI.js.map +1 -0
  20. package/{google-drive.generated-JTJW3HYA.js → google-drive.generated-EFB5FL7H.js} +1 -1
  21. package/google-drive.generated-EFB5FL7H.js.map +1 -0
  22. package/{google-meet.generated-SQAK6E4P.js → google-meet.generated-K2FLJEET.js} +1 -1
  23. package/google-meet.generated-K2FLJEET.js.map +1 -0
  24. package/{google-search-console.generated-PRI3O6UG.js → google-search-console.generated-3ZTIE5VX.js} +1 -1
  25. package/google-search-console.generated-3ZTIE5VX.js.map +1 -0
  26. package/{google-sheets.generated-NZNUFLZM.js → google-sheets.generated-2NO2YMYK.js} +1 -1
  27. package/google-sheets.generated-2NO2YMYK.js.map +1 -0
  28. package/index.js +10 -10
  29. package/{maskdb.generated-T2JIVNT4.js → maskdb.generated-VNT5ANFK.js} +1 -1
  30. package/maskdb.generated-VNT5ANFK.js.map +1 -0
  31. package/package.json +1 -1
  32. package/{slack.generated-V76OAVKH.js → slack.generated-QJKOJ2OP.js} +1 -1
  33. package/slack.generated-QJKOJ2OP.js.map +1 -0
  34. package/{stripe.generated-SC3QH5ZD.js → stripe.generated-2RPKIN5I.js} +1 -1
  35. package/stripe.generated-2RPKIN5I.js.map +1 -0
  36. package/{vercel.generated-NX2R7A4K.js → vercel.generated-FZ6RD7RJ.js} +1 -1
  37. package/vercel.generated-FZ6RD7RJ.js.map +1 -0
  38. package/{youtube.generated-YWLXAYNL.js → youtube.generated-2NDVPMV2.js} +1 -1
  39. package/youtube.generated-2NDVPMV2.js.map +1 -0
  40. package/zero.js +295 -27
  41. package/zero.js.map +1 -1
  42. package/clerk.generated-ZX6FS3MY.js.map +0 -1
  43. package/cloudflare.generated-6N4KWRE3.js.map +0 -1
  44. package/gmail.generated-PL3HVAVP.js.map +0 -1
  45. package/google-analytics.generated-7EAP74EC.js.map +0 -1
  46. package/google-calendar.generated-66JO7MZH.js.map +0 -1
  47. package/google-cloud.generated-H4E5WNYB.js.map +0 -1
  48. package/google-docs.generated-NZYWOUOC.js.map +0 -1
  49. package/google-drive.generated-JTJW3HYA.js.map +0 -1
  50. package/google-meet.generated-SQAK6E4P.js.map +0 -1
  51. package/google-search-console.generated-PRI3O6UG.js.map +0 -1
  52. package/google-sheets.generated-NZNUFLZM.js.map +0 -1
  53. package/maskdb.generated-T2JIVNT4.js.map +0 -1
  54. package/slack.generated-V76OAVKH.js.map +0 -1
  55. package/stripe.generated-SC3QH5ZD.js.map +0 -1
  56. package/vercel.generated-NX2R7A4K.js.map +0 -1
  57. package/youtube.generated-YWLXAYNL.js.map +0 -1
  58. /package/{firewall-placeholder-expansion-FRPU64H3.js.map → firewall-placeholder-expansion-NK7UHGTN.js.map} +0 -0
package/zero.js CHANGED
@@ -178,7 +178,7 @@ import {
178
178
  uploadWebFile,
179
179
  upsertZeroOrgModelProvider,
180
180
  withErrorHandler
181
- } from "./chunk-VTG7YKGH.js";
181
+ } from "./chunk-E4QFFTUC.js";
182
182
  import {
183
183
  CONNECTOR_TYPES,
184
184
  CONNECTOR_TYPE_KEYS,
@@ -191,7 +191,7 @@ import {
191
191
  getConnectorStoredSecretDisplayInfo,
192
192
  getDiagnosticConnectorTypeForRuntimeEnvName,
193
193
  hasRequiredConnectorAuthMethodScopes
194
- } from "./chunk-NUMM3WMG.js";
194
+ } from "./chunk-S3DAXIKY.js";
195
195
  import "./chunk-NR42YJMI.js";
196
196
  import {
197
197
  __toESM,
@@ -6064,7 +6064,7 @@ var GENERATED_RUNTIME_FIREWALL_LOADERS = {
6064
6064
  return (await import("./clearbit.generated-O6YEDZFY.js")).clearbitFirewall;
6065
6065
  },
6066
6066
  "clerk": async () => {
6067
- return (await import("./clerk.generated-ZX6FS3MY.js")).clerkFirewall;
6067
+ return (await import("./clerk.generated-VYPZORXB.js")).clerkFirewall;
6068
6068
  },
6069
6069
  "clickup": async () => {
6070
6070
  return (await import("./clickup.generated-4U5NK3UA.js")).clickupFirewall;
@@ -6073,7 +6073,7 @@ var GENERATED_RUNTIME_FIREWALL_LOADERS = {
6073
6073
  return (await import("./close.generated-RJLZRUPF.js")).closeFirewall;
6074
6074
  },
6075
6075
  "cloudflare": async () => {
6076
- return (await import("./cloudflare.generated-6N4KWRE3.js")).cloudflareFirewall;
6076
+ return (await import("./cloudflare.generated-YPGW4ALF.js")).cloudflareFirewall;
6077
6077
  },
6078
6078
  "coda": async () => {
6079
6079
  return (await import("./coda.generated-VV7Y2ZCR.js")).codaFirewall;
@@ -6199,7 +6199,7 @@ var GENERATED_RUNTIME_FIREWALL_LOADERS = {
6199
6199
  return (await import("./gitlab.generated-VDLFPOB7.js")).gitlabFirewall;
6200
6200
  },
6201
6201
  "gmail": async () => {
6202
- return (await import("./gmail.generated-PL3HVAVP.js")).gmailFirewall;
6202
+ return (await import("./gmail.generated-CXXGCZPP.js")).gmailFirewall;
6203
6203
  },
6204
6204
  "gong": async () => {
6205
6205
  return (await import("./gong.generated-JD4HLOLX.js")).gongFirewall;
@@ -6208,31 +6208,31 @@ var GENERATED_RUNTIME_FIREWALL_LOADERS = {
6208
6208
  return (await import("./google-ads.generated-2JH5PMA7.js")).googleAdsFirewall;
6209
6209
  },
6210
6210
  "google-analytics": async () => {
6211
- return (await import("./google-analytics.generated-7EAP74EC.js")).googleAnalyticsFirewall;
6211
+ return (await import("./google-analytics.generated-LR5RC6K5.js")).googleAnalyticsFirewall;
6212
6212
  },
6213
6213
  "google-calendar": async () => {
6214
- return (await import("./google-calendar.generated-66JO7MZH.js")).googleCalendarFirewall;
6214
+ return (await import("./google-calendar.generated-D4GJ7VO5.js")).googleCalendarFirewall;
6215
6215
  },
6216
6216
  "google-cloud": async () => {
6217
- return (await import("./google-cloud.generated-H4E5WNYB.js")).googleCloudFirewall;
6217
+ return (await import("./google-cloud.generated-753VHV7L.js")).googleCloudFirewall;
6218
6218
  },
6219
6219
  "google-docs": async () => {
6220
- return (await import("./google-docs.generated-NZYWOUOC.js")).googleDocsFirewall;
6220
+ return (await import("./google-docs.generated-XH5A5CNI.js")).googleDocsFirewall;
6221
6221
  },
6222
6222
  "google-drive": async () => {
6223
- return (await import("./google-drive.generated-JTJW3HYA.js")).googleDriveFirewall;
6223
+ return (await import("./google-drive.generated-EFB5FL7H.js")).googleDriveFirewall;
6224
6224
  },
6225
6225
  "google-maps": async () => {
6226
6226
  return (await import("./google-maps.generated-U6ECKZ6E.js")).googleMapsFirewall;
6227
6227
  },
6228
6228
  "google-meet": async () => {
6229
- return (await import("./google-meet.generated-SQAK6E4P.js")).googleMeetFirewall;
6229
+ return (await import("./google-meet.generated-K2FLJEET.js")).googleMeetFirewall;
6230
6230
  },
6231
6231
  "google-search-console": async () => {
6232
- return (await import("./google-search-console.generated-PRI3O6UG.js")).googleSearchConsoleFirewall;
6232
+ return (await import("./google-search-console.generated-3ZTIE5VX.js")).googleSearchConsoleFirewall;
6233
6233
  },
6234
6234
  "google-sheets": async () => {
6235
- return (await import("./google-sheets.generated-NZNUFLZM.js")).googleSheetsFirewall;
6235
+ return (await import("./google-sheets.generated-2NO2YMYK.js")).googleSheetsFirewall;
6236
6236
  },
6237
6237
  "granola": async () => {
6238
6238
  return (await import("./granola.generated-RIGG4QFA.js")).granolaFirewall;
@@ -6352,7 +6352,7 @@ var GENERATED_RUNTIME_FIREWALL_LOADERS = {
6352
6352
  return (await import("./mapbox.generated-EMMM7SWX.js")).mapboxFirewall;
6353
6353
  },
6354
6354
  "maskdb": async () => {
6355
- return (await import("./maskdb.generated-T2JIVNT4.js")).maskdbFirewall;
6355
+ return (await import("./maskdb.generated-VNT5ANFK.js")).maskdbFirewall;
6356
6356
  },
6357
6357
  "massive": async () => {
6358
6358
  return (await import("./massive.generated-5LPRW3UT.js")).massiveFirewall;
@@ -6577,7 +6577,7 @@ var GENERATED_RUNTIME_FIREWALL_LOADERS = {
6577
6577
  return (await import("./similarweb.generated-PCBSSOCD.js")).similarwebFirewall;
6578
6578
  },
6579
6579
  "slack": async () => {
6580
- return (await import("./slack.generated-V76OAVKH.js")).slackFirewall;
6580
+ return (await import("./slack.generated-QJKOJ2OP.js")).slackFirewall;
6581
6581
  },
6582
6582
  "slack-webhook": async () => {
6583
6583
  return (await import("./slack-webhook.generated-XMEEBF47.js")).slackWebhookFirewall;
@@ -6616,7 +6616,7 @@ var GENERATED_RUNTIME_FIREWALL_LOADERS = {
6616
6616
  return (await import("./streak.generated-Y3LFC2JD.js")).streakFirewall;
6617
6617
  },
6618
6618
  "stripe": async () => {
6619
- return (await import("./stripe.generated-SC3QH5ZD.js")).stripeFirewall;
6619
+ return (await import("./stripe.generated-2RPKIN5I.js")).stripeFirewall;
6620
6620
  },
6621
6621
  "supabase": async () => {
6622
6622
  return (await import("./supabase.generated-CIKR6U6G.js")).supabaseFirewall;
@@ -6667,7 +6667,7 @@ var GENERATED_RUNTIME_FIREWALL_LOADERS = {
6667
6667
  return (await import("./v0.generated-VF33O3AD.js")).v0Firewall;
6668
6668
  },
6669
6669
  "vercel": async () => {
6670
- return (await import("./vercel.generated-NX2R7A4K.js")).vercelFirewall;
6670
+ return (await import("./vercel.generated-FZ6RD7RJ.js")).vercelFirewall;
6671
6671
  },
6672
6672
  "wandb": async () => {
6673
6673
  return (await import("./wandb.generated-7RF2F2A3.js")).wandbFirewall;
@@ -6697,7 +6697,7 @@ var GENERATED_RUNTIME_FIREWALL_LOADERS = {
6697
6697
  return (await import("./xero.generated-7XBNR4R7.js")).xeroFirewall;
6698
6698
  },
6699
6699
  "youtube": async () => {
6700
- return (await import("./youtube.generated-YWLXAYNL.js")).youtubeFirewall;
6700
+ return (await import("./youtube.generated-2NDVPMV2.js")).youtubeFirewall;
6701
6701
  },
6702
6702
  "zapier": async () => {
6703
6703
  return (await import("./zapier.generated-DAJBGTEJ.js")).zapierFirewall;
@@ -6736,7 +6736,7 @@ function isRuntimeFirewallConnectorType(type) {
6736
6736
  async function loadExpandedConnectorFirewall(type) {
6737
6737
  const [firewall, { expandFirewallPlaceholders }] = await Promise.all([
6738
6738
  loadGeneratedRuntimeFirewall(type),
6739
- import("./firewall-placeholder-expansion-FRPU64H3.js")
6739
+ import("./firewall-placeholder-expansion-NK7UHGTN.js")
6740
6740
  ]);
6741
6741
  return expandFirewallPlaceholders(firewall, type);
6742
6742
  }
@@ -14962,9 +14962,13 @@ Notes:
14962
14962
 
14963
14963
  // src/commands/zero/maps/index.ts
14964
14964
  init_esm_shims();
14965
+ import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
14966
+ import { dirname as dirname3 } from "path";
14965
14967
  var TRAVEL_MODES = ["driving", "walking", "bicycling", "transit"];
14966
14968
  var PLACE_SEARCH_FIELDSETS = ["pro", "enterprise"];
14967
14969
  var PLACE_DETAIL_FIELDSETS = ["essentials", "pro", "enterprise"];
14970
+ var OSM_LAYERS = ["roads", "buildings", "water", "parks"];
14971
+ var OSM_STYLES = ["standard", "guide"];
14968
14972
  function parseLatitude(value) {
14969
14973
  const latitude = Number(value);
14970
14974
  if (!Number.isFinite(latitude) || latitude < -90 || latitude > 90) {
@@ -14995,6 +14999,15 @@ function parseLimit4(value) {
14995
14999
  }
14996
15000
  return limit;
14997
15001
  }
15002
+ function parseIntegerInRange(value, min, max) {
15003
+ const parsed = Number(value);
15004
+ if (!Number.isInteger(parsed) || parsed < min || parsed > max) {
15005
+ throw new InvalidArgumentError(
15006
+ `value must be an integer from ${min} to ${max}`
15007
+ );
15008
+ }
15009
+ return parsed;
15010
+ }
14998
15011
  function parseTravelMode(value) {
14999
15012
  if (TRAVEL_MODES.includes(value)) {
15000
15013
  return value;
@@ -15019,8 +15032,142 @@ function parsePlaceDetailFields(value) {
15019
15032
  `fields must be one of: ${PLACE_DETAIL_FIELDSETS.join(", ")}`
15020
15033
  );
15021
15034
  }
15022
- function renderMapsResponse(label, response) {
15023
- console.log(source_default.green(`\u2713 ${label}`));
15035
+ function parseBBox(value) {
15036
+ const parts = value.split(",").map((part) => {
15037
+ return part.trim();
15038
+ });
15039
+ if (parts.length !== 4) {
15040
+ throw new InvalidArgumentError("bbox must be west,south,east,north");
15041
+ }
15042
+ const [westRaw, southRaw, eastRaw, northRaw] = parts;
15043
+ if (!westRaw || !southRaw || !eastRaw || !northRaw) {
15044
+ throw new InvalidArgumentError("bbox must be west,south,east,north");
15045
+ }
15046
+ const bbox = {
15047
+ west: parseLongitude(westRaw),
15048
+ south: parseLatitude(southRaw),
15049
+ east: parseLongitude(eastRaw),
15050
+ north: parseLatitude(northRaw)
15051
+ };
15052
+ if (bbox.east <= bbox.west || bbox.north <= bbox.south) {
15053
+ throw new InvalidArgumentError(
15054
+ "bbox east/north must be greater than west/south"
15055
+ );
15056
+ }
15057
+ return bbox;
15058
+ }
15059
+ function parseLatLng(value) {
15060
+ const parts = value.split(",").map((part) => {
15061
+ return part.trim();
15062
+ });
15063
+ if (parts.length !== 2 || !parts[0] || !parts[1]) {
15064
+ throw new InvalidArgumentError("coordinates must be lat,lng");
15065
+ }
15066
+ return {
15067
+ lat: parseLatitude(parts[0]),
15068
+ lng: parseLongitude(parts[1])
15069
+ };
15070
+ }
15071
+ function parseOsmLayers(value) {
15072
+ const layers = [
15073
+ ...new Set(
15074
+ value.split(",").map((layer) => {
15075
+ return layer.trim();
15076
+ }).filter(Boolean)
15077
+ )
15078
+ ];
15079
+ if (layers.length === 0) {
15080
+ throw new InvalidArgumentError("layers must include at least one value");
15081
+ }
15082
+ const invalid = layers.find((layer) => {
15083
+ return !OSM_LAYERS.includes(layer);
15084
+ });
15085
+ if (invalid) {
15086
+ throw new InvalidArgumentError(
15087
+ `layers must be drawn from: ${OSM_LAYERS.join(", ")}`
15088
+ );
15089
+ }
15090
+ return layers;
15091
+ }
15092
+ function parseOsmStyle(value) {
15093
+ if (OSM_STYLES.includes(value)) {
15094
+ return value;
15095
+ }
15096
+ throw new InvalidArgumentError(
15097
+ `style must be one of: ${OSM_STYLES.join(", ")}`
15098
+ );
15099
+ }
15100
+ function parseOsmMarker(value) {
15101
+ const [latRaw, lngRaw, ...labelParts] = value.split(",");
15102
+ if (!latRaw?.trim() || !lngRaw?.trim()) {
15103
+ throw new InvalidArgumentError("marker must be lat,lng or lat,lng,label");
15104
+ }
15105
+ const label = labelParts.join(",").trim();
15106
+ return {
15107
+ lat: parseLatitude(latRaw.trim()),
15108
+ lng: parseLongitude(lngRaw.trim()),
15109
+ ...label ? { label } : {}
15110
+ };
15111
+ }
15112
+ function collectOsmMarker(value, previous) {
15113
+ return [...previous, parseOsmMarker(value)];
15114
+ }
15115
+ function osmAreaPayload(options) {
15116
+ const hasBbox = options.bbox !== void 0;
15117
+ const hasCenterRadius = options.center !== void 0 && options.radius !== void 0;
15118
+ if (hasBbox === hasCenterRadius) {
15119
+ throw new Error("Provide either --bbox or --center with --radius");
15120
+ }
15121
+ return {
15122
+ ...options.bbox ? { bbox: options.bbox } : {},
15123
+ ...options.center ? { center: options.center } : {},
15124
+ ...options.radius !== void 0 ? { radiusMeters: options.radius } : {},
15125
+ layers: options.layers
15126
+ };
15127
+ }
15128
+ function isRecord3(value) {
15129
+ return typeof value === "object" && value !== null && !Array.isArray(value);
15130
+ }
15131
+ function resultRecord(response) {
15132
+ if (!isRecord3(response.result)) {
15133
+ throw new Error("Zero Maps response did not include an object result");
15134
+ }
15135
+ return response.result;
15136
+ }
15137
+ function stringField2(value, key) {
15138
+ const field = value[key];
15139
+ return typeof field === "string" ? field : void 0;
15140
+ }
15141
+ function numberField(value, key) {
15142
+ const field = value[key];
15143
+ return typeof field === "number" ? field : void 0;
15144
+ }
15145
+ async function writeOutputFile(outputPath, content) {
15146
+ await mkdir3(dirname3(outputPath), { recursive: true });
15147
+ await writeFile3(outputPath, content);
15148
+ }
15149
+ async function writeOsmGeoJson(outputPath, response) {
15150
+ const result = resultRecord(response);
15151
+ if (!("geojson" in result)) {
15152
+ throw new Error("Zero Maps OSM download response did not include geojson");
15153
+ }
15154
+ await writeOutputFile(
15155
+ outputPath,
15156
+ `${JSON.stringify(result.geojson, null, 2)}
15157
+ `
15158
+ );
15159
+ }
15160
+ async function writeOsmPng(outputPath, response) {
15161
+ const result = resultRecord(response);
15162
+ const image = result.image;
15163
+ if (!isRecord3(image) || typeof image.base64 !== "string") {
15164
+ throw new Error(
15165
+ "Zero Maps OSM render response did not include a PNG image"
15166
+ );
15167
+ }
15168
+ await writeOutputFile(outputPath, Buffer.from(image.base64, "base64"));
15169
+ }
15170
+ function renderMapsMetadata(response) {
15024
15171
  if (response.provider) {
15025
15172
  console.log(source_default.dim(` Provider: ${response.provider}`));
15026
15173
  }
@@ -15033,9 +15180,27 @@ function renderMapsResponse(label, response) {
15033
15180
  if (response.creditsCharged !== void 0) {
15034
15181
  console.log(source_default.dim(` Credits charged: ${response.creditsCharged}`));
15035
15182
  }
15183
+ }
15184
+ function renderMapsResponse(label, response) {
15185
+ console.log(source_default.green(`\u2713 ${label}`));
15186
+ renderMapsMetadata(response);
15036
15187
  const result = response.result ?? response;
15037
15188
  console.log(JSON.stringify(result, null, 2));
15038
15189
  }
15190
+ function renderOsmFileResponse(label, response, outputPath) {
15191
+ console.log(source_default.green(`\u2713 ${label}`));
15192
+ renderMapsMetadata(response);
15193
+ const result = isRecord3(response.result) ? response.result : {};
15194
+ const featureCount = numberField(result, "featureCount");
15195
+ const attribution = stringField2(result, "attribution");
15196
+ if (featureCount !== void 0) {
15197
+ console.log(source_default.dim(` Features: ${featureCount}`));
15198
+ }
15199
+ if (attribution) {
15200
+ console.log(source_default.dim(` Attribution: ${attribution}`));
15201
+ }
15202
+ console.log(source_default.dim(` Output: ${outputPath}`));
15203
+ }
15039
15204
  async function runMapsRequest(label, endpoint, payload, options) {
15040
15205
  const response = await callZeroMaps(endpoint, payload);
15041
15206
  if (options.json) {
@@ -15136,8 +15301,109 @@ var placesDetailsCommand = new Command().name("details").description("Get detail
15136
15301
  );
15137
15302
  })
15138
15303
  );
15304
+ var osmDownloadCommand = new Command().name("download").description("Download OpenStreetMap vector features as GeoJSON").option(
15305
+ "--bbox <west,south,east,north>",
15306
+ "Bounding box in WGS84 coordinates",
15307
+ parseBBox
15308
+ ).option(
15309
+ "--center <lat,lng>",
15310
+ "Center point in WGS84 coordinates",
15311
+ parseLatLng
15312
+ ).option(
15313
+ "--radius <meters>",
15314
+ "Radius in meters when using --center",
15315
+ parsePositiveInteger3
15316
+ ).option(
15317
+ "--layers <layers>",
15318
+ "Comma-separated layers: roads, buildings, water, parks",
15319
+ parseOsmLayers,
15320
+ OSM_LAYERS
15321
+ ).option("--output <path>", "Write GeoJSON to a file").option("--json", "Print the raw maps response as JSON").action(
15322
+ withErrorHandler(async (options) => {
15323
+ const response = await callZeroMaps(
15324
+ "osm/download",
15325
+ osmAreaPayload(options)
15326
+ );
15327
+ if (options.output) {
15328
+ await writeOsmGeoJson(options.output, response);
15329
+ }
15330
+ if (options.json) {
15331
+ console.log(JSON.stringify(response));
15332
+ return;
15333
+ }
15334
+ if (options.output) {
15335
+ renderOsmFileResponse(
15336
+ "OSM download completed",
15337
+ response,
15338
+ options.output
15339
+ );
15340
+ return;
15341
+ }
15342
+ renderMapsResponse("OSM download completed", response);
15343
+ })
15344
+ );
15345
+ var osmRenderCommand = new Command().name("render").description("Render OpenStreetMap vector features to PNG").option(
15346
+ "--bbox <west,south,east,north>",
15347
+ "Bounding box in WGS84 coordinates",
15348
+ parseBBox
15349
+ ).option(
15350
+ "--center <lat,lng>",
15351
+ "Center point in WGS84 coordinates",
15352
+ parseLatLng
15353
+ ).option(
15354
+ "--radius <meters>",
15355
+ "Radius in meters when using --center",
15356
+ parsePositiveInteger3
15357
+ ).option(
15358
+ "--layers <layers>",
15359
+ "Comma-separated layers: roads, buildings, water, parks",
15360
+ parseOsmLayers,
15361
+ OSM_LAYERS
15362
+ ).option(
15363
+ "--width <px>",
15364
+ "PNG width in pixels, from 320 to 2048",
15365
+ (value) => {
15366
+ return parseIntegerInRange(value, 320, 2048);
15367
+ },
15368
+ 1536
15369
+ ).option(
15370
+ "--height <px>",
15371
+ "PNG height in pixels, from 240 to 2048",
15372
+ (value) => {
15373
+ return parseIntegerInRange(value, 240, 2048);
15374
+ },
15375
+ 1024
15376
+ ).option(
15377
+ "--style <style>",
15378
+ "Render style: standard or guide",
15379
+ parseOsmStyle,
15380
+ "standard"
15381
+ ).option("--title <text>", "Optional title drawn onto the PNG").option(
15382
+ "--marker <lat,lng[,label]>",
15383
+ "Marker to draw; repeat for multiple markers",
15384
+ collectOsmMarker,
15385
+ []
15386
+ ).requiredOption("--output <path>", "Write PNG to a file").option("--json", "Print the raw maps response as JSON").action(
15387
+ withErrorHandler(async (options) => {
15388
+ const response = await callZeroMaps("osm/render", {
15389
+ ...osmAreaPayload(options),
15390
+ width: options.width,
15391
+ height: options.height,
15392
+ style: options.style,
15393
+ title: options.title,
15394
+ markers: options.marker
15395
+ });
15396
+ await writeOsmPng(options.output, response);
15397
+ if (options.json) {
15398
+ console.log(JSON.stringify(response));
15399
+ return;
15400
+ }
15401
+ renderOsmFileResponse("OSM render completed", response, options.output);
15402
+ })
15403
+ );
15404
+ var osmCommand = new Command().name("osm").description("Download and render OpenStreetMap data").addCommand(osmDownloadCommand).addCommand(osmRenderCommand);
15139
15405
  var placesCommand = new Command().name("places").description("Search places and fetch place details").addCommand(placesSearchCommand).addCommand(placesDetailsCommand);
15140
- var zeroMapsCommand = new Command().name("maps").description("Use managed zero maps services").addCommand(geocodeCommand).addCommand(reverseGeocodeCommand).addCommand(directionsCommand).addCommand(placesCommand).addHelpText(
15406
+ var zeroMapsCommand = new Command().name("maps").description("Use managed zero maps services").addCommand(geocodeCommand).addCommand(reverseGeocodeCommand).addCommand(directionsCommand).addCommand(placesCommand).addCommand(osmCommand).addHelpText(
15141
15407
  "after",
15142
15408
  `
15143
15409
  Examples:
@@ -15147,10 +15413,12 @@ Examples:
15147
15413
  Enterprise search: zero maps places search --query "restaurants in SoMa" --fields enterprise --json
15148
15414
  Place details: zero maps places details --place-id <id> --fields essentials --json
15149
15415
  Enterprise details: zero maps places details --place-id <id> --fields enterprise --json
15416
+ Download OSM data: zero maps osm download --bbox -122.43,37.76,-122.40,37.79 --output map.geojson
15417
+ Render OSM PNG: zero maps osm render --center 37.7749,-122.4194 --radius 1200 --output map.png
15150
15418
 
15151
15419
  Notes:
15152
15420
  - Authenticates via ZERO_TOKEN (requires maps:read capability) or a CLI token
15153
- - Google Maps calls and credit billing happen on the vm0 API server
15421
+ - Google Maps and OpenStreetMap calls and credit billing happen on the vm0 API server
15154
15422
  - Use --fields essentials for place details unless paid fields are required`
15155
15423
  );
15156
15424
 
@@ -15613,7 +15881,7 @@ Tip (video understanding):
15613
15881
  // src/commands/zero/resource/index.ts
15614
15882
  init_esm_shims();
15615
15883
  import { createHash as createHash3 } from "crypto";
15616
- import { mkdir as mkdir3, mkdtemp, rm, writeFile as writeFile3 } from "fs/promises";
15884
+ import { mkdir as mkdir4, mkdtemp, rm, writeFile as writeFile4 } from "fs/promises";
15617
15885
  import { tmpdir as tmpdir8 } from "os";
15618
15886
  import path from "path";
15619
15887
  function candidateIds(id) {
@@ -15691,8 +15959,8 @@ var zeroResourceCommand = new Command().name("resource").description("Pull regis
15691
15959
  const outputDir3 = path.resolve(options.dir);
15692
15960
  const tmpDir = await mkdtemp(path.join(tmpdir8(), "zero-resource-"));
15693
15961
  const archivePath = path.join(tmpDir, "resource.tar.gz");
15694
- await mkdir3(outputDir3, { recursive: true });
15695
- await writeFile3(archivePath, buffer);
15962
+ await mkdir4(outputDir3, { recursive: true });
15963
+ await writeFile4(archivePath, buffer);
15696
15964
  try {
15697
15965
  await uo({
15698
15966
  file: archivePath,
@@ -15837,7 +16105,7 @@ function registerZeroCommands(prog, commands) {
15837
16105
  var program = new Command();
15838
16106
  program.name("zero").description(
15839
16107
  "Zero CLI \u2014 interact with the zero platform from inside the sandbox"
15840
- ).version("9.208.2").addHelpText("after", () => {
16108
+ ).version("9.209.1").addHelpText("after", () => {
15841
16109
  return buildZeroHelpText();
15842
16110
  });
15843
16111
  if (process.argv[1]?.endsWith("zero.js") || process.argv[1]?.endsWith("zero.ts") || process.argv[1]?.endsWith("zero")) {