@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
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/zero/logs/index.ts","../src/lib/api/domains/zero-runs.ts","../src/commands/zero/logs/list.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { getZeroRunAgentEvents } from \"../../../lib/api/domains/zero-runs\";\nimport type { RunEvent } from \"@vm0/api-contracts/contracts/runs\";\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/with-error-handler\";\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 { initClient } from \"@vm0/api-contracts/contracts/trpc-contract\";\nimport { zeroRunAgentEventsContract } from \"@vm0/api-contracts/contracts/zero-runs\";\nimport type { AgentEventsResponse } from \"@vm0/api-contracts/contracts/runs\";\nimport { getClientConfig, handleError } from \"../core/client-factory\";\n\ninterface LogPaginationOptions {\n readonly since?: number;\n readonly sinceTime?: number;\n readonly cursor?: string;\n readonly limit?: number;\n readonly order?: \"asc\" | \"desc\";\n}\n\nexport async function getZeroRunAgentEvents(\n id: string,\n options?: LogPaginationOptions,\n): Promise<AgentEventsResponse> {\n const config = await getClientConfig();\n const client = initClient(zeroRunAgentEventsContract, config);\n const result = await client.getAgentEvents({\n params: { id },\n query: {\n since: options?.since,\n sinceTime: options?.sinceTime,\n cursor: options?.cursor,\n limit: options?.limit,\n order: options?.order,\n },\n });\n if (result.status === 200) return result.body;\n handleError(result, `Failed to get zero run events for \"${id}\"`);\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { listZeroLogs } from \"../../../lib/api/domains/zero-logs\";\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/with-error-handler\";\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,26 +1,37 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __createRequire } from "node:module";
3
3
  const require = __createRequire(import.meta.url);
4
+ import {
5
+ zeroMailContract
6
+ } from "./chunk-RTCRU35A.js";
4
7
  import {
5
8
  addRequestedCallbackSearchParams,
6
9
  connectorActionCallbackAvailable,
7
10
  findConnectorStatusItem,
8
11
  printCallbackTurnInstruction,
9
12
  resolveAgentContext
10
- } from "./chunk-F2AM4RWA.js";
13
+ } from "./chunk-RTEEWZUT.js";
11
14
  import {
12
- linkZeroMailDraft,
13
15
  listZeroConnectorCatalogStatus
14
- } from "./chunk-6PN6QGIM.js";
15
- import "./chunk-V7A6ZFHR.js";
16
+ } from "./chunk-U2GQH6AD.js";
17
+ import "./chunk-HZYOJTEE.js";
18
+ import "./chunk-HHHHZMTA.js";
19
+ import "./chunk-DUA6CF7E.js";
20
+ import "./chunk-YDS3X7KB.js";
21
+ import "./chunk-LIYPTQAO.js";
22
+ import "./chunk-SMPSKBAP.js";
23
+ import "./chunk-A6ZRMNM3.js";
24
+ import "./chunk-JV6LM2YC.js";
16
25
  import {
17
26
  getPlatformOrigin
18
- } from "./chunk-BRV4D3P2.js";
19
- import "./chunk-ANOLYIPL.js";
27
+ } from "./chunk-RUKMHBNQ.js";
20
28
  import {
29
+ getClientConfig,
30
+ handleError,
31
+ initClient,
21
32
  source_default,
22
33
  withErrorHandler
23
- } from "./chunk-5ZZI2LSO.js";
34
+ } from "./chunk-GHKWW4NC.js";
24
35
  import "./chunk-32FE3MDA.js";
25
36
  import {
26
37
  Command,
@@ -104,6 +115,26 @@ var connectCommand = new Command().name("connect").description("Get a connect or
104
115
 
105
116
  // src/commands/zero/mail/link.ts
106
117
  init_esm_shims();
118
+
119
+ // src/lib/api/domains/zero-mail.ts
120
+ init_esm_shims();
121
+ async function linkZeroMailDraft(args) {
122
+ const config = await getClientConfig();
123
+ const client = initClient(zeroMailContract, config);
124
+ const result = await client.linkDraft({
125
+ body: {
126
+ threadId: args.threadId,
127
+ agentId: args.agentId,
128
+ gmailDraftId: args.gmailDraftId
129
+ }
130
+ });
131
+ if (result.status === 200) {
132
+ return result.body;
133
+ }
134
+ handleError(result, "Failed to link Gmail draft");
135
+ }
136
+
137
+ // src/commands/zero/mail/link.ts
107
138
  function currentChatThreadId() {
108
139
  const threadId = process.env.ZERO_CHAT_THREAD_ID?.trim();
109
140
  if (!threadId) {
@@ -234,4 +265,4 @@ var zeroMailCommand = new Command().name("mail").description("Review linked Gmai
234
265
  export {
235
266
  zeroMailCommand
236
267
  };
237
- //# sourceMappingURL=mail-L33OSQ2R.js.map
268
+ //# sourceMappingURL=mail-G4SAJSBD.js.map
@@ -0,0 +1 @@
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/lib/api/domains/zero-mail.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/domains/zero-connectors\";\nimport { withErrorHandler } from \"../../../lib/command/with-error-handler\";\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/domains/zero-mail\";\nimport { withErrorHandler } from \"../../../lib/command/with-error-handler\";\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 { initClient } from \"@vm0/api-contracts/contracts/trpc-contract\";\nimport { zeroMailContract } from \"@vm0/api-contracts/contracts/zero-mail\";\n\nimport { getClientConfig, handleError } from \"../core/client-factory\";\n\nexport async function linkZeroMailDraft(args: {\n readonly threadId: string;\n readonly agentId: string;\n readonly gmailDraftId: string;\n}): Promise<{\n readonly mailDraftId: string;\n readonly mailDraftUrl: string;\n}> {\n const config = await getClientConfig();\n const client = initClient(zeroMailContract, config);\n const result = await client.linkDraft({\n body: {\n threadId: args.threadId,\n agentId: args.agentId,\n gmailDraftId: args.gmailDraftId,\n },\n });\n if (result.status === 200) {\n return result.body;\n }\n handleError(result, \"Failed to link Gmail draft\");\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport { listZeroConnectorCatalogStatus } from \"../../../lib/api/domains/zero-connectors\";\nimport { withErrorHandler } from \"../../../lib/command/with-error-handler\";\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":[]}
@@ -2,14 +2,13 @@
2
2
  import { createRequire as __createRequire } from "node:module";
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
- callZeroMaps
6
- } from "./chunk-6PN6QGIM.js";
7
- import "./chunk-V7A6ZFHR.js";
8
- import "./chunk-ANOLYIPL.js";
9
- import {
5
+ ApiRequestError,
6
+ getActiveToken,
7
+ getBaseUrl,
8
+ headersWithCliClientHeaders,
10
9
  source_default,
11
10
  withErrorHandler
12
- } from "./chunk-5ZZI2LSO.js";
11
+ } from "./chunk-GHKWW4NC.js";
13
12
  import "./chunk-32FE3MDA.js";
14
13
  import {
15
14
  Command,
@@ -23,6 +22,61 @@ import {
23
22
  init_esm_shims();
24
23
  import { mkdir, writeFile } from "fs/promises";
25
24
  import { dirname } from "path";
25
+
26
+ // src/lib/api/domains/zero-maps.ts
27
+ init_esm_shims();
28
+ function authenticatedJsonHeaders(token) {
29
+ const headers = {
30
+ Authorization: `Bearer ${token}`,
31
+ "Content-Type": "application/json"
32
+ };
33
+ return headers;
34
+ }
35
+ function isRecord(value) {
36
+ return typeof value === "object" && value !== null && !Array.isArray(value);
37
+ }
38
+ async function parseErrorBody(response) {
39
+ let message = `Zero Maps request failed (HTTP ${response.status})`;
40
+ let code = response.status === 404 ? "NOT_FOUND" : "UNKNOWN";
41
+ try {
42
+ const body = await response.json();
43
+ if (isRecord(body) && isRecord(body.error)) {
44
+ if (typeof body.error.message === "string") {
45
+ message = body.error.message;
46
+ }
47
+ if (typeof body.error.code === "string") {
48
+ code = body.error.code;
49
+ }
50
+ }
51
+ } catch {
52
+ }
53
+ if (response.status === 404 && code === "NOT_FOUND") {
54
+ message = "Zero Maps API is not available on this server yet. Try again after the maps backend is deployed.";
55
+ }
56
+ return { message, code };
57
+ }
58
+ async function callZeroMaps(operation, body) {
59
+ const baseUrl = await getBaseUrl();
60
+ const token = await getActiveToken();
61
+ if (!token) {
62
+ throw new ApiRequestError("Not authenticated", "UNAUTHORIZED", 401);
63
+ }
64
+ const response = await fetch(
65
+ new URL(`/api/zero/maps/${operation}`, baseUrl),
66
+ {
67
+ method: "POST",
68
+ headers: headersWithCliClientHeaders(authenticatedJsonHeaders(token)),
69
+ body: JSON.stringify(body)
70
+ }
71
+ );
72
+ if (!response.ok) {
73
+ const { message, code } = await parseErrorBody(response);
74
+ throw new ApiRequestError(message, code, response.status);
75
+ }
76
+ return await response.json();
77
+ }
78
+
79
+ // src/commands/zero/maps/index.ts
26
80
  var TRAVEL_MODES = ["driving", "walking", "bicycling", "transit"];
27
81
  var PLACE_SEARCH_FIELDSETS = ["pro", "enterprise"];
28
82
  var PLACE_DETAIL_FIELDSETS = ["essentials", "pro", "enterprise"];
@@ -184,11 +238,11 @@ function osmAreaPayload(options) {
184
238
  layers: options.layers
185
239
  };
186
240
  }
187
- function isRecord(value) {
241
+ function isRecord2(value) {
188
242
  return typeof value === "object" && value !== null && !Array.isArray(value);
189
243
  }
190
244
  function resultRecord(response) {
191
- if (!isRecord(response.result)) {
245
+ if (!isRecord2(response.result)) {
192
246
  throw new Error("Zero Maps response did not include an object result");
193
247
  }
194
248
  return response.result;
@@ -219,7 +273,7 @@ async function writeOsmGeoJson(outputPath, response) {
219
273
  async function writeOsmPng(outputPath, response) {
220
274
  const result = resultRecord(response);
221
275
  const image = result.image;
222
- if (!isRecord(image) || typeof image.base64 !== "string") {
276
+ if (!isRecord2(image) || typeof image.base64 !== "string") {
223
277
  throw new Error(
224
278
  "Zero Maps OSM render response did not include a PNG image"
225
279
  );
@@ -249,7 +303,7 @@ function renderMapsResponse(label, response) {
249
303
  function renderOsmFileResponse(label, response, outputPath) {
250
304
  console.log(source_default.green(`\u2713 ${label}`));
251
305
  renderMapsMetadata(response);
252
- const result = isRecord(response.result) ? response.result : {};
306
+ const result = isRecord2(response.result) ? response.result : {};
253
307
  const featureCount = numberField(result, "featureCount");
254
308
  const attribution = stringField(result, "attribution");
255
309
  if (featureCount !== void 0) {
@@ -483,4 +537,4 @@ Notes:
483
537
  export {
484
538
  zeroMapsCommand
485
539
  };
486
- //# sourceMappingURL=maps-D5XTXU5U.js.map
540
+ //# sourceMappingURL=maps-7ANNU3BX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/zero/maps/index.ts","../src/lib/api/domains/zero-maps.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 {\n callZeroMaps,\n type ZeroMapsResponse,\n} from \"../../../lib/api/domains/zero-maps\";\nimport { withErrorHandler } from \"../../../lib/command/with-error-handler\";\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","import { ApiRequestError, getBaseUrl } from \"../core/client-factory\";\nimport { getActiveToken } from \"../config\";\nimport { headersWithCliClientHeaders } from \"../client-headers\";\n\ntype ZeroMapsOperation =\n | \"geocode\"\n | \"reverse-geocode\"\n | \"directions\"\n | \"places/search\"\n | \"places/details\"\n | \"osm/download\"\n | \"osm/render\";\n\nexport interface ZeroMapsResponse {\n readonly operation?: string;\n readonly provider?: string;\n readonly creditsCharged?: number;\n readonly billingCategory?: string;\n readonly billingQuantity?: number;\n readonly result?: unknown;\n}\n\nfunction authenticatedJsonHeaders(token: string): Record<string, string> {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n };\n return headers;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nasync function parseErrorBody(\n response: Response,\n): Promise<{ message: string; code: string }> {\n let message = `Zero Maps request failed (HTTP ${response.status})`;\n let code = response.status === 404 ? \"NOT_FOUND\" : \"UNKNOWN\";\n\n try {\n const body: unknown = await response.json();\n if (isRecord(body) && isRecord(body.error)) {\n if (typeof body.error.message === \"string\") {\n message = body.error.message;\n }\n if (typeof body.error.code === \"string\") {\n code = body.error.code;\n }\n }\n } catch {\n // Keep the status-based fallback when the response is not JSON.\n }\n\n if (response.status === 404 && code === \"NOT_FOUND\") {\n message =\n \"Zero Maps API is not available on this server yet. Try again after the maps backend is deployed.\";\n }\n\n return { message, code };\n}\n\nexport async function callZeroMaps(\n operation: ZeroMapsOperation,\n body: Record<string, unknown>,\n): Promise<ZeroMapsResponse> {\n const baseUrl = await getBaseUrl();\n const token = await getActiveToken();\n if (!token) {\n throw new ApiRequestError(\"Not authenticated\", \"UNAUTHORIZED\", 401);\n }\n\n const response = await fetch(\n new URL(`/api/zero/maps/${operation}`, baseUrl),\n {\n method: \"POST\",\n headers: headersWithCliClientHeaders(authenticatedJsonHeaders(token)),\n body: JSON.stringify(body),\n },\n );\n\n if (!response.ok) {\n const { message, code } = await parseErrorBody(response);\n throw new ApiRequestError(message, code, response.status);\n }\n\n return (await response.json()) as ZeroMapsResponse;\n}\n"],"mappings":"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","names":["isRecord"]}
@@ -5,17 +5,17 @@ import {
5
5
  formatModelPolicyStatus,
6
6
  formatModelProviderRoute,
7
7
  getModelProviderRouteKind
8
- } from "./chunk-QC63TUJC.js";
8
+ } from "./chunk-C62A6LD6.js";
9
9
  import {
10
10
  listZeroModelPolicies
11
- } from "./chunk-6PN6QGIM.js";
12
- import "./chunk-V7A6ZFHR.js";
13
- import "./chunk-ANOLYIPL.js";
11
+ } from "./chunk-SA4DYSBR.js";
12
+ import "./chunk-CEJGHPF3.js";
13
+ import "./chunk-JV6LM2YC.js";
14
14
  import {
15
15
  getVm0ModelPriceTier,
16
16
  source_default,
17
17
  withErrorHandler
18
- } from "./chunk-5ZZI2LSO.js";
18
+ } from "./chunk-GHKWW4NC.js";
19
19
  import "./chunk-32FE3MDA.js";
20
20
  import {
21
21
  Command
@@ -89,4 +89,4 @@ export {
89
89
  switchCommand,
90
90
  zeroModelCommand
91
91
  };
92
- //# sourceMappingURL=model-ZFMRECDM.js.map
92
+ //# sourceMappingURL=model-DSPDCJLB.js.map
@@ -0,0 +1 @@
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/domains/zero-model-policies\";\nimport { withErrorHandler } from \"../../../lib/command/with-error-handler\";\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":[]}
@@ -5,16 +5,16 @@ import {
5
5
  formatModelPolicyStatus,
6
6
  getModelProviderRouteKind,
7
7
  getModelProviderTypeLabel
8
- } from "./chunk-QC63TUJC.js";
8
+ } from "./chunk-C62A6LD6.js";
9
9
  import {
10
10
  listZeroModelPolicies
11
- } from "./chunk-6PN6QGIM.js";
12
- import "./chunk-V7A6ZFHR.js";
13
- import "./chunk-ANOLYIPL.js";
11
+ } from "./chunk-SA4DYSBR.js";
12
+ import "./chunk-CEJGHPF3.js";
13
+ import "./chunk-JV6LM2YC.js";
14
14
  import {
15
15
  source_default,
16
16
  withErrorHandler
17
- } from "./chunk-5ZZI2LSO.js";
17
+ } from "./chunk-GHKWW4NC.js";
18
18
  import "./chunk-32FE3MDA.js";
19
19
  import {
20
20
  Command
@@ -73,4 +73,4 @@ export {
73
73
  setCommand,
74
74
  zeroModelProviderCommand
75
75
  };
76
- //# sourceMappingURL=model-provider-EZZ2DRYZ.js.map
76
+ //# sourceMappingURL=model-provider-RZQ45PNG.js.map
@@ -0,0 +1 @@
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/domains/zero-model-policies\";\nimport { withErrorHandler } from \"../../../lib/command/with-error-handler\";\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":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "9.278.0",
3
+ "version": "9.278.1",
4
4
  "description": "Zero command-line interface for vm0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -4,15 +4,17 @@ const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  ZERO_PEOPLE_SEARCH_DEFAULT_LIMIT,
6
6
  ZERO_PEOPLE_SEARCH_MAX_LIMIT,
7
- callZeroPeopleSearch,
7
+ zeroPeopleSearchContract,
8
8
  zeroPeopleSearchRequestSchema
9
- } from "./chunk-6PN6QGIM.js";
10
- import "./chunk-V7A6ZFHR.js";
11
- import "./chunk-ANOLYIPL.js";
9
+ } from "./chunk-GY7D76EZ.js";
10
+ import "./chunk-JV6LM2YC.js";
12
11
  import {
12
+ getClientConfig,
13
+ handleError,
14
+ initClient,
13
15
  source_default,
14
16
  withErrorHandler
15
- } from "./chunk-5ZZI2LSO.js";
17
+ } from "./chunk-GHKWW4NC.js";
16
18
  import "./chunk-32FE3MDA.js";
17
19
  import {
18
20
  Command,
@@ -25,6 +27,20 @@ import {
25
27
 
26
28
  // src/commands/zero/people-search/index.ts
27
29
  init_esm_shims();
30
+
31
+ // src/lib/api/domains/zero-people-search.ts
32
+ init_esm_shims();
33
+ async function callZeroPeopleSearch(body) {
34
+ const config = await getClientConfig();
35
+ const client = initClient(zeroPeopleSearchContract, config);
36
+ const result = await client.search({ headers: {}, body });
37
+ if (result.status === 200) {
38
+ return result.body;
39
+ }
40
+ handleError(result, "Failed to search for people");
41
+ }
42
+
43
+ // src/commands/zero/people-search/index.ts
28
44
  function parseLimit(value) {
29
45
  if (!/^\d+$/.test(value)) {
30
46
  throw new InvalidArgumentError(
@@ -125,4 +141,4 @@ Notes:
125
141
  export {
126
142
  zeroPeopleSearchCommand
127
143
  };
128
- //# sourceMappingURL=people-search-PFTIO2QS.js.map
144
+ //# sourceMappingURL=people-search-I7PUMF5M.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/zero/people-search/index.ts","../src/lib/api/domains/zero-people-search.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 { callZeroPeopleSearch } from \"../../../lib/api/domains/zero-people-search\";\nimport type { ZeroPeopleSearchResponse } from \"@vm0/api-contracts/contracts/zero-people-search\";\nimport { withErrorHandler } from \"../../../lib/command/with-error-handler\";\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","import {\n zeroPeopleSearchContract,\n type ZeroPeopleSearchRequest,\n type ZeroPeopleSearchResponse,\n} from \"@vm0/api-contracts/contracts/zero-people-search\";\nimport { initClient } from \"@vm0/api-contracts/contracts/trpc-contract\";\n\nimport { getClientConfig, handleError } from \"../core/client-factory\";\n\nexport async function callZeroPeopleSearch(\n body: ZeroPeopleSearchRequest,\n): Promise<ZeroPeopleSearchResponse> {\n const config = await getClientConfig();\n const client = initClient(zeroPeopleSearchContract, config);\n const result = await client.search({ headers: {}, body });\n if (result.status === 200) {\n return result.body;\n }\n handleError(result, \"Failed to search for people\");\n}\n"],"mappings":"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","names":[]}