@vm0/cli 9.270.0 → 9.271.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/{agent-GWRPSBTH.js → agent-O4PIZ7NO.js} +7 -7
  2. package/{banking-P6SCAW3O.js → banking-K3T7FGVL.js} +5 -5
  3. package/{browser-JY5OKWWH.js → browser-ZUXV2DZI.js} +5 -5
  4. package/{chat-7RH3RGZQ.js → chat-FQ65YTRM.js} +6 -6
  5. package/{chunk-P46KNOFG.js → chunk-CCUKVMAH.js} +2 -2
  6. package/{chunk-JUE2IIB6.js → chunk-D7TEG7WN.js} +3 -3
  7. package/{chunk-4PFAYD37.js → chunk-EINTZ5MX.js} +21 -6
  8. package/chunk-EINTZ5MX.js.map +1 -0
  9. package/{chunk-72ZGOFYI.js → chunk-JXUQQIUP.js} +12 -4
  10. package/chunk-JXUQQIUP.js.map +1 -0
  11. package/{chunk-ZUHSC7WF.js → chunk-MD3YWUKO.js} +2 -18
  12. package/chunk-MD3YWUKO.js.map +1 -0
  13. package/{chunk-WFGX6IFZ.js → chunk-MOWAU52B.js} +2 -2
  14. package/{chunk-IYGQB2IF.js → chunk-NGDZ3M3I.js} +2 -2
  15. package/{chunk-6AA2D344.js → chunk-RFTCX5UZ.js} +2 -2
  16. package/{chunk-W25EDDGL.js → chunk-TC7IZRA2.js} +2 -2
  17. package/{chunk-VNXDSWLZ.js → chunk-TM6A5MNI.js} +185 -94
  18. package/chunk-TM6A5MNI.js.map +1 -0
  19. package/{chunk-NGVPA5PP.js → chunk-TZDXFY6G.js} +289 -394
  20. package/{chunk-NGVPA5PP.js.map → chunk-TZDXFY6G.js.map} +1 -1
  21. package/{chunk-IWQVF27E.js → chunk-VSL4HRIA.js} +2 -2
  22. package/{chunk-JSH7H3SB.js → chunk-X7YXT2UE.js} +14 -10
  23. package/chunk-X7YXT2UE.js.map +1 -0
  24. package/{computer-use-KIPDCGWU.js → computer-use-LAD5XLHX.js} +5 -5
  25. package/{connector-Y5RELY3X.js → connector-AVTEZ5M4.js} +9 -9
  26. package/{connector-Y5RELY3X.js.map → connector-AVTEZ5M4.js.map} +1 -1
  27. package/{credit-PYPLO2DH.js → credit-I45PC4IZ.js} +7 -7
  28. package/{developer-support-BTVJRES3.js → developer-support-HG2427DE.js} +5 -5
  29. package/{doctor-6O6JP2WS.js → doctor-NEF5PDLF.js} +7 -7
  30. package/{feishu-JED4BVTP.js → feishu-C7TLUZNW.js} +11 -7
  31. package/{feishu-JED4BVTP.js.map → feishu-C7TLUZNW.js.map} +1 -1
  32. package/{finance-3FHYRVG2.js → finance-QRINPXNY.js} +5 -5
  33. package/{generate-37C27FP7.js → generate-OR4TSIMU.js} +8 -8
  34. package/{github-EH2LQE7I.js → github-B6FLS3YK.js} +11 -7
  35. package/{github-EH2LQE7I.js.map → github-B6FLS3YK.js.map} +1 -1
  36. package/{goal-XECU5EWN.js → goal-QXSEQGAT.js} +5 -5
  37. package/{host-NEOIQLMT.js → host-4TKBODTL.js} +5 -5
  38. package/{logs-ETQTIIG4.js → logs-WBT4C34D.js} +8 -8
  39. package/{mail-PZKZHOCR.js → mail-GVDB4DW2.js} +7 -7
  40. package/{maps-7M6YJZYG.js → maps-7PWULA7U.js} +5 -5
  41. package/{model-PGAUO6W5.js → model-54YGVJAR.js} +6 -6
  42. package/{model-provider-W5UVHH6U.js → model-provider-ZPDGFYK3.js} +6 -6
  43. package/{org-EUVQDJTX.js → org-4IZEIH7U.js} +5 -5
  44. package/package.json +1 -1
  45. package/{people-search-ZN6RLZXA.js → people-search-3MYEUXPL.js} +5 -5
  46. package/{phone-HXFIS3AF.js → phone-374WD72N.js} +11 -7
  47. package/{phone-HXFIS3AF.js.map → phone-374WD72N.js.map} +1 -1
  48. package/{preference-PRQX4SKA.js → preference-6MJRMHWU.js} +5 -5
  49. package/{resource-JY6BVLHP.js → resource-LHAF45BR.js} +6 -6
  50. package/{scrape-K4JOJDHX.js → scrape-IWNRA5Y6.js} +5 -5
  51. package/{search-REY6675M.js → search-D65TMXEQ.js} +8 -8
  52. package/{secret-IHJS2ING.js → secret-HCD3ZCX2.js} +5 -5
  53. package/{slack-JTSV74J5.js → slack-R4LKBTX6.js} +10 -6
  54. package/slack-R4LKBTX6.js.map +1 -0
  55. package/{teams-7WJFP33N.js → teams-3JJJ2G3A.js} +11 -7
  56. package/{teams-7WJFP33N.js.map → teams-3JJJ2G3A.js.map} +1 -1
  57. package/{telegram-AC6MPDBH.js → telegram-2E2UM67J.js} +11 -7
  58. package/{telegram-AC6MPDBH.js.map → telegram-2E2UM67J.js.map} +1 -1
  59. package/{upgrade-RHBB33B6.js → upgrade-J6FYUUYV.js} +4 -4
  60. package/{variable-7T7HFEXZ.js → variable-YXJ6NH3N.js} +5 -5
  61. package/{video-KAR3CSKG.js → video-GYS2CSQF.js} +4 -4
  62. package/{weather-2TV7QHNI.js → weather-N5IWRZPG.js} +5 -5
  63. package/{web-SHKUVKKL.js → web-LPR6C2K7.js} +5 -5
  64. package/{web-search-TLA5G6MO.js → web-search-BT6BDI5E.js} +5 -5
  65. package/{whoami-E7OQS7EL.js → whoami-YV26HEXS.js} +7 -7
  66. package/{workflow-J5PQ5AXJ.js → workflow-T2R3IE2A.js} +6 -6
  67. package/zero.js +44 -44
  68. package/chunk-4PFAYD37.js.map +0 -1
  69. package/chunk-72ZGOFYI.js.map +0 -1
  70. package/chunk-JSH7H3SB.js.map +0 -1
  71. package/chunk-VNXDSWLZ.js.map +0 -1
  72. package/chunk-ZUHSC7WF.js.map +0 -1
  73. package/slack-JTSV74J5.js.map +0 -1
  74. /package/{agent-GWRPSBTH.js.map → agent-O4PIZ7NO.js.map} +0 -0
  75. /package/{banking-P6SCAW3O.js.map → banking-K3T7FGVL.js.map} +0 -0
  76. /package/{browser-JY5OKWWH.js.map → browser-ZUXV2DZI.js.map} +0 -0
  77. /package/{chat-7RH3RGZQ.js.map → chat-FQ65YTRM.js.map} +0 -0
  78. /package/{chunk-P46KNOFG.js.map → chunk-CCUKVMAH.js.map} +0 -0
  79. /package/{chunk-JUE2IIB6.js.map → chunk-D7TEG7WN.js.map} +0 -0
  80. /package/{chunk-WFGX6IFZ.js.map → chunk-MOWAU52B.js.map} +0 -0
  81. /package/{chunk-IYGQB2IF.js.map → chunk-NGDZ3M3I.js.map} +0 -0
  82. /package/{chunk-6AA2D344.js.map → chunk-RFTCX5UZ.js.map} +0 -0
  83. /package/{chunk-W25EDDGL.js.map → chunk-TC7IZRA2.js.map} +0 -0
  84. /package/{chunk-IWQVF27E.js.map → chunk-VSL4HRIA.js.map} +0 -0
  85. /package/{computer-use-KIPDCGWU.js.map → computer-use-LAD5XLHX.js.map} +0 -0
  86. /package/{credit-PYPLO2DH.js.map → credit-I45PC4IZ.js.map} +0 -0
  87. /package/{developer-support-BTVJRES3.js.map → developer-support-HG2427DE.js.map} +0 -0
  88. /package/{doctor-6O6JP2WS.js.map → doctor-NEF5PDLF.js.map} +0 -0
  89. /package/{finance-3FHYRVG2.js.map → finance-QRINPXNY.js.map} +0 -0
  90. /package/{generate-37C27FP7.js.map → generate-OR4TSIMU.js.map} +0 -0
  91. /package/{goal-XECU5EWN.js.map → goal-QXSEQGAT.js.map} +0 -0
  92. /package/{host-NEOIQLMT.js.map → host-4TKBODTL.js.map} +0 -0
  93. /package/{logs-ETQTIIG4.js.map → logs-WBT4C34D.js.map} +0 -0
  94. /package/{mail-PZKZHOCR.js.map → mail-GVDB4DW2.js.map} +0 -0
  95. /package/{maps-7M6YJZYG.js.map → maps-7PWULA7U.js.map} +0 -0
  96. /package/{model-PGAUO6W5.js.map → model-54YGVJAR.js.map} +0 -0
  97. /package/{model-provider-W5UVHH6U.js.map → model-provider-ZPDGFYK3.js.map} +0 -0
  98. /package/{org-EUVQDJTX.js.map → org-4IZEIH7U.js.map} +0 -0
  99. /package/{people-search-ZN6RLZXA.js.map → people-search-3MYEUXPL.js.map} +0 -0
  100. /package/{preference-PRQX4SKA.js.map → preference-6MJRMHWU.js.map} +0 -0
  101. /package/{resource-JY6BVLHP.js.map → resource-LHAF45BR.js.map} +0 -0
  102. /package/{scrape-K4JOJDHX.js.map → scrape-IWNRA5Y6.js.map} +0 -0
  103. /package/{search-REY6675M.js.map → search-D65TMXEQ.js.map} +0 -0
  104. /package/{secret-IHJS2ING.js.map → secret-HCD3ZCX2.js.map} +0 -0
  105. /package/{upgrade-RHBB33B6.js.map → upgrade-J6FYUUYV.js.map} +0 -0
  106. /package/{variable-7T7HFEXZ.js.map → variable-YXJ6NH3N.js.map} +0 -0
  107. /package/{video-KAR3CSKG.js.map → video-GYS2CSQF.js.map} +0 -0
  108. /package/{weather-2TV7QHNI.js.map → weather-N5IWRZPG.js.map} +0 -0
  109. /package/{web-SHKUVKKL.js.map → web-LPR6C2K7.js.map} +0 -0
  110. /package/{web-search-TLA5G6MO.js.map → web-search-BT6BDI5E.js.map} +0 -0
  111. /package/{whoami-E7OQS7EL.js.map → whoami-YV26HEXS.js.map} +0 -0
  112. /package/{workflow-J5PQ5AXJ.js.map → workflow-T2R3IE2A.js.map} +0 -0
@@ -25,8 +25,8 @@ import {
25
25
  setZeroOrgVariable,
26
26
  updateZeroOrg,
27
27
  upsertZeroOrgModelProvider
28
- } from "./chunk-NGVPA5PP.js";
29
- import "./chunk-72ZGOFYI.js";
28
+ } from "./chunk-TZDXFY6G.js";
29
+ import "./chunk-JXUQQIUP.js";
30
30
  import "./chunk-MA22KQYU.js";
31
31
  import {
32
32
  ApiRequestError,
@@ -39,8 +39,8 @@ import {
39
39
  hasAuthMethods,
40
40
  source_default,
41
41
  withErrorHandler
42
- } from "./chunk-JUE2IIB6.js";
43
- import "./chunk-ZUHSC7WF.js";
42
+ } from "./chunk-D7TEG7WN.js";
43
+ import "./chunk-MD3YWUKO.js";
44
44
  import {
45
45
  Command
46
46
  } from "./chunk-CCWPKGTB.js";
@@ -879,4 +879,4 @@ var zeroOrgCommand = new Command().name("org").description("Manage organization
879
879
  export {
880
880
  zeroOrgCommand
881
881
  };
882
- //# sourceMappingURL=org-EUVQDJTX.js.map
882
+ //# sourceMappingURL=org-4IZEIH7U.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "9.270.0",
3
+ "version": "9.271.0",
4
4
  "description": "Zero command-line interface for vm0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -6,14 +6,14 @@ import {
6
6
  ZERO_PEOPLE_SEARCH_MAX_LIMIT,
7
7
  callZeroPeopleSearch,
8
8
  zeroPeopleSearchRequestSchema
9
- } from "./chunk-NGVPA5PP.js";
10
- import "./chunk-72ZGOFYI.js";
9
+ } from "./chunk-TZDXFY6G.js";
10
+ import "./chunk-JXUQQIUP.js";
11
11
  import "./chunk-MA22KQYU.js";
12
12
  import {
13
13
  source_default,
14
14
  withErrorHandler
15
- } from "./chunk-JUE2IIB6.js";
16
- import "./chunk-ZUHSC7WF.js";
15
+ } from "./chunk-D7TEG7WN.js";
16
+ import "./chunk-MD3YWUKO.js";
17
17
  import {
18
18
  Command,
19
19
  InvalidArgumentError,
@@ -125,4 +125,4 @@ Notes:
125
125
  export {
126
126
  zeroPeopleSearchCommand
127
127
  };
128
- //# sourceMappingURL=people-search-ZN6RLZXA.js.map
128
+ //# sourceMappingURL=people-search-3MYEUXPL.js.map
@@ -6,14 +6,14 @@ import {
6
6
  downloadPhoneFile,
7
7
  initPhoneFileUpload,
8
8
  sendPhoneMessage
9
- } from "./chunk-NGVPA5PP.js";
10
- import "./chunk-72ZGOFYI.js";
9
+ } from "./chunk-TZDXFY6G.js";
10
+ import "./chunk-JXUQQIUP.js";
11
11
  import "./chunk-MA22KQYU.js";
12
12
  import {
13
13
  source_default,
14
14
  withErrorHandler
15
- } from "./chunk-JUE2IIB6.js";
16
- import "./chunk-ZUHSC7WF.js";
15
+ } from "./chunk-D7TEG7WN.js";
16
+ import "./chunk-MD3YWUKO.js";
17
17
  import {
18
18
  Command
19
19
  } from "./chunk-CCWPKGTB.js";
@@ -163,12 +163,16 @@ Output:
163
163
  const prepared = await initPhoneFileUpload({
164
164
  filename,
165
165
  contentType,
166
- length: fileSize
166
+ length: fileSize,
167
+ supportsUploadHeaders: true
167
168
  });
168
169
  const fileContent = readFileSync2(options.file);
169
170
  const uploadResponse = await fetch(prepared.uploadUrl, {
170
171
  method: "PUT",
171
- headers: { "Content-Type": prepared.contentType },
172
+ headers: {
173
+ "Content-Type": prepared.contentType,
174
+ ...prepared.uploadHeaders
175
+ },
172
176
  body: new Uint8Array(fileContent)
173
177
  });
174
178
  if (!uploadResponse.ok) {
@@ -200,4 +204,4 @@ Examples:
200
204
  export {
201
205
  zeroPhoneCommand
202
206
  };
203
- //# sourceMappingURL=phone-HXFIS3AF.js.map
207
+ //# sourceMappingURL=phone-374WD72N.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/zero/phone/index.ts","../src/commands/zero/phone/download-file.ts","../src/commands/zero/phone/message.ts","../src/commands/zero/phone/upload-file.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { downloadFileCommand } from \"./download-file\";\nimport { messageCommand } from \"./message\";\nimport { uploadFileCommand } from \"./upload-file\";\n\nexport const zeroPhoneCommand = new Command()\n .name(\"phone\")\n .description(\"Send AgentPhone messages, upload files, and download media\")\n .addCommand(messageCommand)\n .addCommand(downloadFileCommand)\n .addCommand(uploadFileCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n Send a message: zero phone message --to +15551234567 -t \"Hello!\"\n Upload a file: zero phone upload-file -f /tmp/report.pdf --to +15551234567\n Download a file: zero phone download-file <file-id> -o /tmp/out.jpg`,\n );\n","import { basename, join } from \"path\";\nimport { tmpdir } from \"os\";\nimport { Command } from \"commander\";\nimport { downloadPhoneFile } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nfunction defaultOutPath(fileId: string): string {\n return join(tmpdir(), `phone-${basename(fileId)}`);\n}\n\nexport const downloadFileCommand = new Command()\n .name(\"download-file\")\n .description(\"Download an AgentPhone media file by id\")\n .argument(\n \"<file-id>\",\n \"AgentPhone message id from an [AgentPhone file] block\",\n )\n .option(\n \"-o, --out <path>\",\n \"Output path for the downloaded file (default: /tmp/phone-<file-id>)\",\n )\n .addHelpText(\n \"after\",\n `\nExamples:\n Download to default temp path: zero phone download-file msg_123\n Download to explicit path: zero phone download-file msg_123 -o /tmp/photo.jpg\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"path\":\"/tmp/phone-msg_123\",\"mimetype\":\"image/jpeg\",\"size\":12345}\n\nHow to read the downloaded file:\n - Images (png/jpg/gif/webp/svg): open the file path with your image viewing tool\n - Videos (mp4/mov/webm): transcribe audio first with\n zero video transcribe --url <download-url>\n or extract frames with\n ffmpeg -i <path> -vf \"fps=1\" -q:v 2 /tmp/<file-id>_frame_%03d.jpg\n - PDF/text/csv/json/markdown: read the file directly`,\n )\n .action(\n withErrorHandler(async (fileId: string, options: { out?: string }) => {\n const outPath = options.out ?? defaultOutPath(fileId);\n const result = await downloadPhoneFile(fileId, outPath);\n console.log(JSON.stringify(result));\n }),\n );\n","import { readFileSync } from \"fs\";\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { sendPhoneMessage } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nexport const messageCommand = new Command()\n .name(\"message\")\n .description(\"Send an AgentPhone text message\")\n .requiredOption(\"--to <phone>\", \"Connected phone handle to message\")\n .option(\"--agent-id <id>\", \"AgentPhone agent ID (inferred when omitted)\")\n .option(\"-t, --text <message>\", \"Message text\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Send a message: zero phone message --to +15551234567 -t \"Hello!\"\n From stdin: printf \"Hello!\" | zero phone message --to +15551234567\n\nNotes:\n - The phone handle must already be connected to the authenticated VM0 user\n - AgentPhone agent ID is inferred from the conversation when omitted`,\n )\n .action(\n withErrorHandler(\n async (options: { to: string; agentId?: string; text?: string }) => {\n let text = options.text;\n if (!text && !process.stdin.isTTY) {\n try {\n text = readFileSync(\"/dev/stdin\", \"utf8\").trim();\n } catch {\n // stdin not readable (e.g. test runner with no piped input);\n // fall through to the missing-text validation below.\n }\n }\n\n if (!text) {\n throw new Error(\"Either --text or piped stdin must be provided\", {\n cause: new Error(\n 'Usage: zero phone message --to +15551234567 -t \"your message\"',\n ),\n });\n }\n\n const result = await sendPhoneMessage({\n toNumber: options.to,\n text,\n agentphoneAgentId: options.agentId,\n });\n\n console.log(\n chalk.green(`✓ Message sent (message_id: ${result.messageId})`),\n );\n },\n ),\n );\n","import { readFileSync, statSync } from \"fs\";\nimport { basename, extname } from \"path\";\nimport { Command } from \"commander\";\nimport { completePhoneFileUpload, initPhoneFileUpload } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nconst MIME_BY_EXTENSION: Record<string, string> = {\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".mp4\": \"video/mp4\",\n \".webm\": \"video/webm\",\n \".mov\": \"video/quicktime\",\n \".pdf\": \"application/pdf\",\n \".txt\": \"text/plain\",\n \".csv\": \"text/csv\",\n \".md\": \"text/markdown\",\n \".json\": \"application/json\",\n};\n\nfunction inferContentType(localPath: string): string {\n const ext = extname(localPath).toLowerCase();\n return MIME_BY_EXTENSION[ext] ?? \"application/octet-stream\";\n}\n\nexport const uploadFileCommand = new Command()\n .name(\"upload-file\")\n .description(\"Upload a local file to an AgentPhone conversation\")\n .requiredOption(\"-f, --file <path>\", \"Local file path to upload\")\n .requiredOption(\"--to <phone>\", \"Connected phone handle to message\")\n .option(\"--agent-id <id>\", \"AgentPhone agent ID (inferred when omitted)\")\n .option(\"--caption <text>\", \"Caption to accompany the file\")\n .option(\"--content-type <mime>\", \"Override inferred content type\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Upload a file: zero phone upload-file -f /tmp/report.pdf --to +15551234567\n With a caption: zero phone upload-file -f /tmp/photo.jpg --to +15551234567 --caption \"Here it is\"\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"messageId\":\"msg_123\",\"toNumber\":\"+15551234567\",\"filename\":\"report.pdf\",\"mimetype\":\"application/pdf\",\"size\":12345,\"url\":\"https://...\"}`,\n )\n .action(\n withErrorHandler(\n async (options: {\n file: string;\n to: string;\n agentId?: string;\n caption?: string;\n contentType?: string;\n }) => {\n let fileSize: number;\n try {\n const stat = statSync(options.file);\n if (!stat.isFile()) {\n throw new Error(`Not a regular file: ${options.file}`);\n }\n fileSize = stat.size;\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"Not \")) {\n throw error;\n }\n throw new Error(`File not found: ${options.file}`);\n }\n\n if (fileSize === 0) {\n throw new Error(\"File is empty\");\n }\n\n const filename = basename(options.file);\n const contentType =\n options.contentType ?? inferContentType(options.file);\n\n const prepared = await initPhoneFileUpload({\n filename,\n contentType,\n length: fileSize,\n });\n\n const fileContent = readFileSync(options.file);\n const uploadResponse = await fetch(prepared.uploadUrl, {\n method: \"PUT\",\n headers: { \"Content-Type\": prepared.contentType },\n body: new Uint8Array(fileContent),\n });\n\n if (!uploadResponse.ok) {\n throw new Error(\n `File upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`,\n );\n }\n\n const result = await completePhoneFileUpload({\n uploadId: prepared.uploadId,\n toNumber: options.to,\n agentphoneAgentId: options.agentId,\n contentType: prepared.contentType,\n caption: options.caption,\n });\n\n console.log(JSON.stringify(result));\n },\n ),\n );\n"],"mappings":"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","names":["readFileSync","basename","basename","readFileSync"]}
1
+ {"version":3,"sources":["../src/commands/zero/phone/index.ts","../src/commands/zero/phone/download-file.ts","../src/commands/zero/phone/message.ts","../src/commands/zero/phone/upload-file.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { downloadFileCommand } from \"./download-file\";\nimport { messageCommand } from \"./message\";\nimport { uploadFileCommand } from \"./upload-file\";\n\nexport const zeroPhoneCommand = new Command()\n .name(\"phone\")\n .description(\"Send AgentPhone messages, upload files, and download media\")\n .addCommand(messageCommand)\n .addCommand(downloadFileCommand)\n .addCommand(uploadFileCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n Send a message: zero phone message --to +15551234567 -t \"Hello!\"\n Upload a file: zero phone upload-file -f /tmp/report.pdf --to +15551234567\n Download a file: zero phone download-file <file-id> -o /tmp/out.jpg`,\n );\n","import { basename, join } from \"path\";\nimport { tmpdir } from \"os\";\nimport { Command } from \"commander\";\nimport { downloadPhoneFile } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nfunction defaultOutPath(fileId: string): string {\n return join(tmpdir(), `phone-${basename(fileId)}`);\n}\n\nexport const downloadFileCommand = new Command()\n .name(\"download-file\")\n .description(\"Download an AgentPhone media file by id\")\n .argument(\n \"<file-id>\",\n \"AgentPhone message id from an [AgentPhone file] block\",\n )\n .option(\n \"-o, --out <path>\",\n \"Output path for the downloaded file (default: /tmp/phone-<file-id>)\",\n )\n .addHelpText(\n \"after\",\n `\nExamples:\n Download to default temp path: zero phone download-file msg_123\n Download to explicit path: zero phone download-file msg_123 -o /tmp/photo.jpg\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"path\":\"/tmp/phone-msg_123\",\"mimetype\":\"image/jpeg\",\"size\":12345}\n\nHow to read the downloaded file:\n - Images (png/jpg/gif/webp/svg): open the file path with your image viewing tool\n - Videos (mp4/mov/webm): transcribe audio first with\n zero video transcribe --url <download-url>\n or extract frames with\n ffmpeg -i <path> -vf \"fps=1\" -q:v 2 /tmp/<file-id>_frame_%03d.jpg\n - PDF/text/csv/json/markdown: read the file directly`,\n )\n .action(\n withErrorHandler(async (fileId: string, options: { out?: string }) => {\n const outPath = options.out ?? defaultOutPath(fileId);\n const result = await downloadPhoneFile(fileId, outPath);\n console.log(JSON.stringify(result));\n }),\n );\n","import { readFileSync } from \"fs\";\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { sendPhoneMessage } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nexport const messageCommand = new Command()\n .name(\"message\")\n .description(\"Send an AgentPhone text message\")\n .requiredOption(\"--to <phone>\", \"Connected phone handle to message\")\n .option(\"--agent-id <id>\", \"AgentPhone agent ID (inferred when omitted)\")\n .option(\"-t, --text <message>\", \"Message text\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Send a message: zero phone message --to +15551234567 -t \"Hello!\"\n From stdin: printf \"Hello!\" | zero phone message --to +15551234567\n\nNotes:\n - The phone handle must already be connected to the authenticated VM0 user\n - AgentPhone agent ID is inferred from the conversation when omitted`,\n )\n .action(\n withErrorHandler(\n async (options: { to: string; agentId?: string; text?: string }) => {\n let text = options.text;\n if (!text && !process.stdin.isTTY) {\n try {\n text = readFileSync(\"/dev/stdin\", \"utf8\").trim();\n } catch {\n // stdin not readable (e.g. test runner with no piped input);\n // fall through to the missing-text validation below.\n }\n }\n\n if (!text) {\n throw new Error(\"Either --text or piped stdin must be provided\", {\n cause: new Error(\n 'Usage: zero phone message --to +15551234567 -t \"your message\"',\n ),\n });\n }\n\n const result = await sendPhoneMessage({\n toNumber: options.to,\n text,\n agentphoneAgentId: options.agentId,\n });\n\n console.log(\n chalk.green(`✓ Message sent (message_id: ${result.messageId})`),\n );\n },\n ),\n );\n","import { readFileSync, statSync } from \"fs\";\nimport { basename, extname } from \"path\";\nimport { Command } from \"commander\";\nimport { completePhoneFileUpload, initPhoneFileUpload } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nconst MIME_BY_EXTENSION: Record<string, string> = {\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".mp4\": \"video/mp4\",\n \".webm\": \"video/webm\",\n \".mov\": \"video/quicktime\",\n \".pdf\": \"application/pdf\",\n \".txt\": \"text/plain\",\n \".csv\": \"text/csv\",\n \".md\": \"text/markdown\",\n \".json\": \"application/json\",\n};\n\nfunction inferContentType(localPath: string): string {\n const ext = extname(localPath).toLowerCase();\n return MIME_BY_EXTENSION[ext] ?? \"application/octet-stream\";\n}\n\nexport const uploadFileCommand = new Command()\n .name(\"upload-file\")\n .description(\"Upload a local file to an AgentPhone conversation\")\n .requiredOption(\"-f, --file <path>\", \"Local file path to upload\")\n .requiredOption(\"--to <phone>\", \"Connected phone handle to message\")\n .option(\"--agent-id <id>\", \"AgentPhone agent ID (inferred when omitted)\")\n .option(\"--caption <text>\", \"Caption to accompany the file\")\n .option(\"--content-type <mime>\", \"Override inferred content type\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Upload a file: zero phone upload-file -f /tmp/report.pdf --to +15551234567\n With a caption: zero phone upload-file -f /tmp/photo.jpg --to +15551234567 --caption \"Here it is\"\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"messageId\":\"msg_123\",\"toNumber\":\"+15551234567\",\"filename\":\"report.pdf\",\"mimetype\":\"application/pdf\",\"size\":12345,\"url\":\"https://...\"}`,\n )\n .action(\n withErrorHandler(\n async (options: {\n file: string;\n to: string;\n agentId?: string;\n caption?: string;\n contentType?: string;\n }) => {\n let fileSize: number;\n try {\n const stat = statSync(options.file);\n if (!stat.isFile()) {\n throw new Error(`Not a regular file: ${options.file}`);\n }\n fileSize = stat.size;\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"Not \")) {\n throw error;\n }\n throw new Error(`File not found: ${options.file}`);\n }\n\n if (fileSize === 0) {\n throw new Error(\"File is empty\");\n }\n\n const filename = basename(options.file);\n const contentType =\n options.contentType ?? inferContentType(options.file);\n\n const prepared = await initPhoneFileUpload({\n filename,\n contentType,\n length: fileSize,\n supportsUploadHeaders: true,\n });\n\n const fileContent = readFileSync(options.file);\n const uploadResponse = await fetch(prepared.uploadUrl, {\n method: \"PUT\",\n headers: {\n \"Content-Type\": prepared.contentType,\n ...prepared.uploadHeaders,\n },\n body: new Uint8Array(fileContent),\n });\n\n if (!uploadResponse.ok) {\n throw new Error(\n `File upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`,\n );\n }\n\n const result = await completePhoneFileUpload({\n uploadId: prepared.uploadId,\n toNumber: options.to,\n agentphoneAgentId: options.agentId,\n contentType: prepared.contentType,\n caption: options.caption,\n });\n\n console.log(JSON.stringify(result));\n },\n ),\n );\n"],"mappings":"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","names":["readFileSync","basename","basename","readFileSync"]}
@@ -8,14 +8,14 @@ import {
8
8
  import {
9
9
  getZeroUserPreferences,
10
10
  updateZeroUserPreferences
11
- } from "./chunk-NGVPA5PP.js";
12
- import "./chunk-72ZGOFYI.js";
11
+ } from "./chunk-TZDXFY6G.js";
12
+ import "./chunk-JXUQQIUP.js";
13
13
  import "./chunk-MA22KQYU.js";
14
14
  import {
15
15
  source_default,
16
16
  withErrorHandler
17
- } from "./chunk-JUE2IIB6.js";
18
- import "./chunk-ZUHSC7WF.js";
17
+ } from "./chunk-D7TEG7WN.js";
18
+ import "./chunk-MD3YWUKO.js";
19
19
  import {
20
20
  Command
21
21
  } from "./chunk-CCWPKGTB.js";
@@ -106,4 +106,4 @@ var zeroPreferenceCommand = new Command().name("preference").description("View o
106
106
  export {
107
107
  zeroPreferenceCommand
108
108
  };
109
- //# sourceMappingURL=preference-PRQX4SKA.js.map
109
+ //# sourceMappingURL=preference-6MJRMHWU.js.map
@@ -10,17 +10,17 @@ import {
10
10
  findTool,
11
11
  findVideoTemplate,
12
12
  findWebsiteTemplateResource
13
- } from "./chunk-VNXDSWLZ.js";
13
+ } from "./chunk-TM6A5MNI.js";
14
14
  import {
15
15
  getRegistryResourceDownload
16
- } from "./chunk-NGVPA5PP.js";
17
- import "./chunk-72ZGOFYI.js";
16
+ } from "./chunk-TZDXFY6G.js";
17
+ import "./chunk-JXUQQIUP.js";
18
18
  import "./chunk-MA22KQYU.js";
19
19
  import {
20
20
  source_default,
21
21
  withErrorHandler
22
- } from "./chunk-JUE2IIB6.js";
23
- import "./chunk-ZUHSC7WF.js";
22
+ } from "./chunk-D7TEG7WN.js";
23
+ import "./chunk-MD3YWUKO.js";
24
24
  import {
25
25
  Command
26
26
  } from "./chunk-CCWPKGTB.js";
@@ -3110,4 +3110,4 @@ export {
3110
3110
  findRegistryResourceForPull,
3111
3111
  zeroResourceCommand
3112
3112
  };
3113
- //# sourceMappingURL=resource-JY6BVLHP.js.map
3113
+ //# sourceMappingURL=resource-LHAF45BR.js.map
@@ -5,14 +5,14 @@ import {
5
5
  callZeroScrape,
6
6
  zeroScrapeFormatSchema,
7
7
  zeroScrapeModeSchema
8
- } from "./chunk-NGVPA5PP.js";
9
- import "./chunk-72ZGOFYI.js";
8
+ } from "./chunk-TZDXFY6G.js";
9
+ import "./chunk-JXUQQIUP.js";
10
10
  import "./chunk-MA22KQYU.js";
11
11
  import {
12
12
  source_default,
13
13
  withErrorHandler
14
- } from "./chunk-JUE2IIB6.js";
15
- import "./chunk-ZUHSC7WF.js";
14
+ } from "./chunk-D7TEG7WN.js";
15
+ import "./chunk-MD3YWUKO.js";
16
16
  import {
17
17
  Command,
18
18
  InvalidArgumentError,
@@ -97,4 +97,4 @@ Notes:
97
97
  export {
98
98
  zeroScrapeCommand
99
99
  };
100
- //# sourceMappingURL=scrape-K4JOJDHX.js.map
100
+ //# sourceMappingURL=scrape-IWNRA5Y6.js.map
@@ -5,25 +5,25 @@ import {
5
5
  parseSearchQuery,
6
6
  parseTime,
7
7
  runLogsSearch
8
- } from "./chunk-4PFAYD37.js";
8
+ } from "./chunk-EINTZ5MX.js";
9
9
  import {
10
10
  formatIsoTimestamp,
11
11
  isUuid,
12
12
  parseBoundedLogCount
13
13
  } from "./chunk-FKYDKKID.js";
14
14
  import "./chunk-LN2ATWKS.js";
15
- import "./chunk-VNXDSWLZ.js";
15
+ import "./chunk-TM6A5MNI.js";
16
16
  import {
17
17
  searchZeroChat
18
- } from "./chunk-NGVPA5PP.js";
19
- import "./chunk-72ZGOFYI.js";
18
+ } from "./chunk-TZDXFY6G.js";
19
+ import "./chunk-JXUQQIUP.js";
20
20
  import "./chunk-MA22KQYU.js";
21
21
  import {
22
22
  source_default,
23
23
  withErrorHandler
24
- } from "./chunk-JUE2IIB6.js";
25
- import "./chunk-JSH7H3SB.js";
26
- import "./chunk-ZUHSC7WF.js";
24
+ } from "./chunk-D7TEG7WN.js";
25
+ import "./chunk-X7YXT2UE.js";
26
+ import "./chunk-MD3YWUKO.js";
27
27
  import {
28
28
  Command
29
29
  } from "./chunk-CCWPKGTB.js";
@@ -200,4 +200,4 @@ export {
200
200
  buildSlackRecipe,
201
201
  zeroSearchCommand
202
202
  };
203
- //# sourceMappingURL=search-REY6675M.js.map
203
+ //# sourceMappingURL=search-D65TMXEQ.js.map
@@ -10,14 +10,14 @@ import {
10
10
  deleteZeroSecret,
11
11
  listZeroSecrets,
12
12
  setZeroSecret
13
- } from "./chunk-NGVPA5PP.js";
14
- import "./chunk-72ZGOFYI.js";
13
+ } from "./chunk-TZDXFY6G.js";
14
+ import "./chunk-JXUQQIUP.js";
15
15
  import "./chunk-MA22KQYU.js";
16
16
  import {
17
17
  source_default,
18
18
  withErrorHandler
19
- } from "./chunk-JUE2IIB6.js";
20
- import "./chunk-ZUHSC7WF.js";
19
+ } from "./chunk-D7TEG7WN.js";
20
+ import "./chunk-MD3YWUKO.js";
21
21
  import {
22
22
  Command
23
23
  } from "./chunk-CCWPKGTB.js";
@@ -147,4 +147,4 @@ var zeroSecretCommand = new Command().name("secret").description("Read or write
147
147
  export {
148
148
  zeroSecretCommand
149
149
  };
150
- //# sourceMappingURL=secret-IHJS2ING.js.map
150
+ //# sourceMappingURL=secret-HCD3ZCX2.js.map
@@ -7,16 +7,16 @@ import {
7
7
  initSlackFileUpload,
8
8
  materializeSlackFileUpload,
9
9
  sendSlackMessage
10
- } from "./chunk-NGVPA5PP.js";
10
+ } from "./chunk-TZDXFY6G.js";
11
11
  import {
12
12
  inferWebUploadContentType
13
- } from "./chunk-72ZGOFYI.js";
13
+ } from "./chunk-JXUQQIUP.js";
14
14
  import "./chunk-MA22KQYU.js";
15
15
  import {
16
16
  source_default,
17
17
  withErrorHandler
18
- } from "./chunk-JUE2IIB6.js";
19
- import "./chunk-ZUHSC7WF.js";
18
+ } from "./chunk-D7TEG7WN.js";
19
+ import "./chunk-MD3YWUKO.js";
20
20
  import {
21
21
  Command
22
22
  } from "./chunk-CCWPKGTB.js";
@@ -157,7 +157,10 @@ async function uploadCanonicalBody(initialized, contentType, fileContent) {
157
157
  }
158
158
  const uploadResponse = await fetch(initialized.uploadUrl, {
159
159
  method: "PUT",
160
- headers: { "Content-Type": contentType },
160
+ headers: {
161
+ "Content-Type": contentType,
162
+ ...initialized.uploadHeaders
163
+ },
161
164
  body: fileContent
162
165
  });
163
166
  if (!uploadResponse.ok) {
@@ -261,6 +264,7 @@ async function uploadFile(options) {
261
264
  const initialized = await initSlackFileUpload({
262
265
  filename,
263
266
  length: file.size,
267
+ supportsUploadHeaders: true,
264
268
  canonical: {
265
269
  operationId,
266
270
  contentType,
@@ -346,4 +350,4 @@ Examples:
346
350
  export {
347
351
  zeroSlackCommand
348
352
  };
349
- //# sourceMappingURL=slack-JTSV74J5.js.map
353
+ //# sourceMappingURL=slack-R4LKBTX6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/zero/slack/index.ts","../src/commands/zero/slack/message/index.ts","../src/commands/zero/slack/message/send.ts","../src/commands/zero/slack/upload-file.ts","../src/commands/zero/slack/download-file.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { zeroSlackMessageCommand } from \"./message\";\nimport { uploadFileCommand } from \"./upload-file\";\nimport { downloadFileCommand } from \"./download-file\";\n\nexport const zeroSlackCommand = new Command()\n .name(\"slack\")\n .description(\n \"Send messages, upload files, and download files from Slack as the bot\",\n )\n .addCommand(zeroSlackMessageCommand)\n .addCommand(uploadFileCommand)\n .addCommand(downloadFileCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n Send a message: zero slack message send -c <channel-id> -t \"Hello!\"\n Reply in a thread: zero slack message send -c <channel-id> --thread <ts> -t \"reply\"\n Upload a file: zero slack upload-file -f /tmp/report.pdf -c <channel-id>\n Download a file: zero slack download-file <file-id> -o /tmp/out.png`,\n );\n","import { Command } from \"commander\";\nimport { sendCommand } from \"./send\";\n\nexport const zeroSlackMessageCommand = new Command()\n .name(\"message\")\n .description(\"Manage Slack messages\")\n .addCommand(sendCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n zero slack message send -c <channel-id> -t \"Hello!\"`,\n );\n","import { readFileSync } from \"fs\";\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { sendSlackMessage } from \"../../../../lib/api\";\nimport { withErrorHandler } from \"../../../../lib/command\";\n\nexport const sendCommand = new Command()\n .name(\"send\")\n .description(\"Send a message to a Slack channel or DM a user\")\n .option(\"-c, --channel <id>\", \"Channel ID\")\n .option(\"-u, --user <id>\", 'Slack user ID for DM (use \"me\" for yourself)')\n .option(\"-t, --text <message>\", \"Message text\")\n .option(\"--thread <ts>\", \"Thread timestamp for replies\")\n .option(\"--blocks <json>\", \"Block Kit JSON string\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Simple message: zero slack message send -c C01234 -t \"Hello!\"\n DM a user: zero slack message send -u U0A8V9X98QJ -t \"Hello!\"\n DM yourself: zero slack message send -u me -t \"Hello!\"\n Reply in thread: zero slack message send -c C01234 --thread 1234567890.123456 -t \"reply\"\n Rich blocks: zero slack message send -c C01234 --blocks '[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*Bold*\"}}]'\n\nNotes:\n - Either --channel or --user is required; they are mutually exclusive\n - Either --text or --blocks is required; both can be used together`,\n )\n .action(\n withErrorHandler(\n async (options: {\n channel?: string;\n user?: string;\n text?: string;\n thread?: string;\n blocks?: string;\n }) => {\n let text = options.text;\n const { channel, user, thread, blocks: blocksStr } = options;\n\n // Validate mutual exclusion: exactly one of --channel or --user\n if (!channel && !user) {\n throw new Error(\"Either --channel or --user must be provided\", {\n cause: new Error(\n 'Usage: zero slack message send -c CHANNEL_ID -t \"your message\"\\n zero slack message send -u USER_ID -t \"your message\"',\n ),\n });\n }\n if (channel && user) {\n throw new Error(\"--channel and --user are mutually exclusive\", {\n cause: new Error(\n \"Provide either --channel to send to a channel or --user to DM a user, not both\",\n ),\n });\n }\n\n // Read from stdin if text not provided and stdin is not a TTY\n // (isTTY is true only for an interactive terminal, undefined when piped).\n if (!text && !process.stdin.isTTY) {\n try {\n text = readFileSync(\"/dev/stdin\", \"utf8\").trim();\n } catch {\n // stdin not readable (e.g. test runner with no piped input);\n // fall through to the missing-text validation below.\n }\n }\n\n // Parse blocks JSON if provided\n let blocks: Array<{ type: string; [key: string]: unknown }> | undefined;\n if (blocksStr) {\n try {\n blocks = JSON.parse(blocksStr) as Array<{\n type: string;\n [key: string]: unknown;\n }>;\n } catch {\n throw new Error(\"Invalid JSON for --blocks flag\", {\n cause: new Error(\n \"Provide a valid JSON array of Block Kit blocks\",\n ),\n });\n }\n }\n\n // Validate at least one of text or blocks\n if (!text && !blocks) {\n throw new Error(\"Either --text or --blocks must be provided\", {\n cause: new Error(\n 'Usage: zero slack message send -c CHANNEL_ID -t \"your message\"',\n ),\n });\n }\n\n const result = await sendSlackMessage({\n channel: channel || undefined,\n user: user || undefined,\n text: text || undefined,\n threadTs: thread,\n blocks,\n });\n\n const tsInfo = result.ts ? ` (ts: ${result.ts})` : \"\";\n console.log(chalk.green(`✓ Message sent${tsInfo}`));\n },\n ),\n );\n","import { createHash, randomUUID } from \"node:crypto\";\nimport { statSync, readFileSync } from \"fs\";\nimport { basename } from \"path\";\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport type {\n SlackUploadInitResponse,\n SlackUploadMaterializeResponse,\n} from \"@vm0/api-contracts/contracts/integrations\";\nimport {\n completeSlackFileUpload,\n inferWebUploadContentType,\n initSlackFileUpload,\n materializeSlackFileUpload,\n} from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\ninterface UploadFileOptions {\n readonly file: string;\n readonly channel: string;\n readonly thread?: string;\n readonly title?: string;\n readonly comment?: string;\n readonly contentType?: string;\n readonly operationId?: string;\n}\n\ntype DirectUploadInitialization = Extract<\n SlackUploadInitResponse,\n { fileId: string }\n>;\ntype CanonicalUploadInitialization = Extract<\n SlackUploadInitResponse,\n { kind: \"canonical\" }\n>;\ntype PendingSlackDelivery = Extract<\n SlackUploadMaterializeResponse[\"delivery\"],\n { status: \"pending\" }\n>;\n\nfunction readUploadFile(path: string): {\n readonly content: Buffer;\n readonly size: number;\n} {\n let size: number;\n try {\n size = statSync(path).size;\n } catch {\n throw new Error(`File not found: ${path}`);\n }\n if (size === 0) {\n throw new Error(\"File is empty\");\n }\n return { content: readFileSync(path), size };\n}\n\nfunction warnDeliveryRetry(operationId: string): void {\n console.warn(chalk.dim(` Retry with --operation-id ${operationId}`));\n}\n\nasync function uploadDirectlyToSlack(\n initialized: DirectUploadInitialization,\n options: UploadFileOptions,\n fileContent: Buffer,\n): Promise<void> {\n const uploadResponse = await fetch(initialized.uploadUrl, {\n method: \"POST\",\n body: fileContent,\n });\n if (!uploadResponse.ok) {\n throw new Error(\n `File upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`,\n );\n }\n const result = await completeSlackFileUpload({\n fileId: initialized.fileId,\n channel: options.channel,\n threadTs: options.thread,\n title: options.title,\n initialComment: options.comment,\n });\n console.log(chalk.green(`✓ File uploaded (file_id: ${result.fileId})`));\n console.log(chalk.dim(` permalink: ${result.permalink}`));\n}\n\nasync function uploadCanonicalBody(\n initialized: CanonicalUploadInitialization,\n contentType: string,\n fileContent: Buffer,\n): Promise<void> {\n if (!initialized.uploadUrl) {\n return;\n }\n const uploadResponse = await fetch(initialized.uploadUrl, {\n method: \"PUT\",\n headers: {\n \"Content-Type\": contentType,\n ...initialized.uploadHeaders,\n },\n body: fileContent,\n });\n if (!uploadResponse.ok) {\n throw new Error(\n `Canonical file upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`,\n );\n }\n}\n\nasync function uploadPendingSlackBody(\n delivery: PendingSlackDelivery,\n fileContent: Buffer,\n): Promise<string | undefined> {\n try {\n const uploadResponse = await fetch(delivery.uploadUrl, {\n method: \"POST\",\n body: fileContent,\n });\n if (!uploadResponse.ok) {\n return `Slack upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`;\n }\n return undefined;\n } catch (error) {\n return error instanceof Error ? error.message : \"Slack upload failed\";\n }\n}\n\nasync function completeCanonicalSlackDelivery(args: {\n readonly initialized: CanonicalUploadInitialization;\n readonly delivery: PendingSlackDelivery;\n readonly options: UploadFileOptions;\n readonly fileContent: Buffer;\n}): Promise<void> {\n const uploadError = await uploadPendingSlackBody(\n args.delivery,\n args.fileContent,\n );\n let result: Awaited<ReturnType<typeof completeSlackFileUpload>>;\n try {\n result = await completeSlackFileUpload({\n fileId: args.delivery.fileId,\n channel: args.options.channel,\n ...(args.options.thread ? { threadTs: args.options.thread } : {}),\n ...(args.options.title ? { title: args.options.title } : {}),\n ...(args.options.comment ? { initialComment: args.options.comment } : {}),\n canonicalAssetId: args.initialized.assetId,\n operationId: args.initialized.operationId,\n ...(uploadError ? { uploadError } : {}),\n });\n } catch (error) {\n console.warn(\n chalk.yellow(\n `⚠ Slack delivery status could not be recorded: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n ),\n );\n warnDeliveryRetry(args.initialized.operationId);\n return;\n }\n if (result.deliveryStatus === \"failed\") {\n console.warn(\n chalk.yellow(\n `⚠ Slack delivery failed: ${result.deliveryError ?? \"Unknown error\"}`,\n ),\n );\n warnDeliveryRetry(args.initialized.operationId);\n return;\n }\n console.log(chalk.green(`✓ Delivered to Slack (file_id: ${result.fileId})`));\n console.log(chalk.dim(` permalink: ${result.permalink}`));\n}\n\nasync function publishCanonicalFile(\n initialized: CanonicalUploadInitialization,\n options: UploadFileOptions,\n contentType: string,\n fileContent: Buffer,\n): Promise<void> {\n await uploadCanonicalBody(initialized, contentType, fileContent);\n const materialized = await materializeSlackFileUpload({\n assetId: initialized.assetId,\n operationId: initialized.operationId,\n });\n console.log(\n chalk.green(`✓ File published (asset_id: ${materialized.assetId})`),\n );\n console.log(chalk.dim(` url: ${materialized.url}`));\n\n if (materialized.delivery.status === \"delivered\") {\n console.log(\n chalk.green(\n `✓ Delivered to Slack (file_id: ${materialized.delivery.fileId})`,\n ),\n );\n console.log(chalk.dim(` permalink: ${materialized.delivery.permalink}`));\n return;\n }\n if (materialized.delivery.status === \"failed\") {\n console.warn(\n chalk.yellow(`⚠ Slack delivery failed: ${materialized.delivery.message}`),\n );\n warnDeliveryRetry(initialized.operationId);\n return;\n }\n await completeCanonicalSlackDelivery({\n initialized,\n delivery: materialized.delivery,\n options,\n fileContent,\n });\n}\n\nasync function uploadFile(options: UploadFileOptions): Promise<void> {\n const file = readUploadFile(options.file);\n const filename = basename(options.file);\n const rawContentType =\n options.contentType ?? inferWebUploadContentType(options.file);\n const contentType =\n rawContentType.split(\";\")[0]?.trim().toLowerCase() ?? rawContentType;\n const operationId = options.operationId ?? randomUUID();\n const checksumSha256 = createHash(\"sha256\")\n .update(file.content)\n .digest(\"hex\");\n const initialized = await initSlackFileUpload({\n filename,\n length: file.size,\n supportsUploadHeaders: true,\n canonical: {\n operationId,\n contentType,\n checksumSha256,\n channel: options.channel,\n threadTs: options.thread,\n title: options.title,\n initialComment: options.comment,\n },\n });\n\n if (\"fileId\" in initialized) {\n await uploadDirectlyToSlack(initialized, options, file.content);\n return;\n }\n await publishCanonicalFile(initialized, options, contentType, file.content);\n}\n\nexport const uploadFileCommand = new Command()\n .name(\"upload-file\")\n .description(\"Upload a file to a Slack channel as the bot\")\n .requiredOption(\"-f, --file <path>\", \"Local file path to upload\")\n .requiredOption(\"-c, --channel <id>\", \"Slack channel ID\")\n .option(\"--thread <ts>\", \"Thread timestamp to post as a reply\")\n .option(\"--title <title>\", \"Display title for the file\")\n .option(\"--comment <text>\", \"Initial comment to accompany the file\")\n .option(\"--content-type <mime>\", \"Override inferred content type\")\n .option(\"--operation-id <uuid>\", \"Reuse a failed upload operation\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Upload a file: zero slack upload-file -f /tmp/report.pdf -c C01234\n Upload to thread: zero slack upload-file -f /tmp/log.txt -c C01234 --thread 1234567890.123456\n With title and comment: zero slack upload-file -f /tmp/data.csv -c C01234 --title \"Daily Report\" --comment \"Here's the report\"\n\nNotes:\n - Uses the bot token (not user SLACK_TOKEN), so no files:write permission is needed\n - Run-scoped calls publish to VM0 storage before Slack delivery\n - Returns canonical asset details and Slack delivery status`,\n )\n .action(withErrorHandler(uploadFile));\n","import { basename, join } from \"path\";\nimport { tmpdir } from \"os\";\nimport { Command } from \"commander\";\nimport { downloadSlackFile } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\n/**\n * Derive a local output path for a Slack file id.\n * Uses the system temp directory; extension is appended later once the\n * mimetype is known.\n *\n * `basename` strips any path separators from `fileId` so a hostile id like\n * `../etc/passwd` cannot escape `tmpdir()`.\n */\nfunction defaultOutPath(fileId: string): string {\n return join(tmpdir(), `slack-${basename(fileId)}`);\n}\n\nexport const downloadFileCommand = new Command()\n .name(\"download-file\")\n .description(\"Download a Slack file by id using the bot token\")\n .argument(\"<file-id>\", \"Slack file id (e.g. F01234ABCD)\")\n .option(\n \"-o, --out <path>\",\n \"Output path for the downloaded file (default: /tmp/slack-<file-id>)\",\n )\n .addHelpText(\n \"after\",\n `\nExamples:\n Download to default temp path: zero slack download-file F01234ABCD\n Download to explicit path: zero slack download-file F01234ABCD -o /tmp/image.png\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"path\":\"/tmp/slack-F01234ABCD\",\"mimetype\":\"image/png\",\"size\":12345}\n\nHow to read the downloaded file:\n - Images (png/jpg/gif/webp/svg): open the file path with your image viewing tool\n - Videos (mp4/mov/webm): transcribe audio first with\n zero video transcribe --url <download-url>\n or extract frames with\n ffmpeg -i <path> -vf \"fps=1\" -q:v 2 /tmp/<file-id>_frame_%03d.jpg\n - PDF/text/csv/json/markdown: read the file directly\n\nNotes:\n - Uses the bot token on the server side; no user Slack token is needed\n - Streams the file bytes directly to disk`,\n )\n .action(\n withErrorHandler(async (fileId: string, options: { out?: string }) => {\n const outPath = options.out ?? defaultOutPath(fileId);\n const result = await downloadSlackFile(fileId, outPath);\n console.log(JSON.stringify(result));\n }),\n );\n"],"mappings":"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","names":["readFileSync","readFileSync","basename","basename"]}
@@ -6,14 +6,14 @@ import {
6
6
  downloadTeamsFile,
7
7
  initTeamsFileUpload,
8
8
  sendTeamsMessage
9
- } from "./chunk-NGVPA5PP.js";
10
- import "./chunk-72ZGOFYI.js";
9
+ } from "./chunk-TZDXFY6G.js";
10
+ import "./chunk-JXUQQIUP.js";
11
11
  import "./chunk-MA22KQYU.js";
12
12
  import {
13
13
  source_default,
14
14
  withErrorHandler
15
- } from "./chunk-JUE2IIB6.js";
16
- import "./chunk-ZUHSC7WF.js";
15
+ } from "./chunk-D7TEG7WN.js";
16
+ import "./chunk-MD3YWUKO.js";
17
17
  import {
18
18
  Command
19
19
  } from "./chunk-CCWPKGTB.js";
@@ -207,12 +207,16 @@ Notes:
207
207
  const prepared = await initTeamsFileUpload({
208
208
  filename,
209
209
  contentType,
210
- length: fileSize
210
+ length: fileSize,
211
+ supportsUploadHeaders: true
211
212
  });
212
213
  const fileContent = readFileSync2(options.file);
213
214
  const uploadResponse = await fetch(prepared.uploadUrl, {
214
215
  method: "PUT",
215
- headers: { "Content-Type": prepared.contentType },
216
+ headers: {
217
+ "Content-Type": prepared.contentType,
218
+ ...prepared.uploadHeaders
219
+ },
216
220
  body: new Uint8Array(fileContent)
217
221
  });
218
222
  if (!uploadResponse.ok) {
@@ -280,4 +284,4 @@ Examples:
280
284
  export {
281
285
  zeroTeamsCommand
282
286
  };
283
- //# sourceMappingURL=teams-7WJFP33N.js.map
287
+ //# sourceMappingURL=teams-3JJJ2G3A.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/zero/teams/index.ts","../src/commands/zero/teams/message/index.ts","../src/commands/zero/teams/message/send.ts","../src/commands/zero/teams/upload-file.ts","../src/commands/zero/teams/download-file.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { zeroTeamsMessageCommand } from \"./message\";\nimport { uploadFileCommand } from \"./upload-file\";\nimport { downloadFileCommand } from \"./download-file\";\n\nexport const zeroTeamsCommand = new Command()\n .name(\"teams\")\n .description(\n \"Send messages, upload files, and download files from Microsoft Teams as the bot\",\n )\n .addCommand(zeroTeamsMessageCommand)\n .addCommand(uploadFileCommand)\n .addCommand(downloadFileCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n Send a message: zero teams message send -c <conversation-id> -t \"Hello!\"\n DM a user: zero teams message send -u me -t \"Hello!\"\n Reply in a thread: zero teams message send -c <conversation-id> --thread <activity-id> -t \"reply\"\n Upload a file: zero teams upload-file -f /tmp/report.pdf -c <conversation-id>\n Download a file: zero teams download-file <file-id> -o /tmp/out.png`,\n );\n","import { Command } from \"commander\";\nimport { sendCommand } from \"./send\";\n\nexport const zeroTeamsMessageCommand = new Command()\n .name(\"message\")\n .description(\"Manage Microsoft Teams messages\")\n .addCommand(sendCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n zero teams message send -c <conversation-id> -t \"Hello!\"\n zero teams message send -u me -t \"Hello!\"`,\n );\n","import { readFileSync } from \"fs\";\nimport { Command } from \"commander\";\nimport type { SendTeamsMessageBody } from \"@vm0/api-contracts/contracts/integrations\";\nimport chalk from \"chalk\";\nimport { sendTeamsMessage } from \"../../../../lib/api\";\nimport { withErrorHandler } from \"../../../../lib/command\";\n\ntype TeamsCardInput = NonNullable<SendTeamsMessageBody[\"card\"]>;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction parseTeamsCard(value: string): TeamsCardInput {\n let parsed: unknown;\n try {\n parsed = JSON.parse(value);\n } catch {\n throw new Error(\"Invalid JSON for --card flag\", {\n cause: new Error(\"Provide a valid Adaptive Card JSON object\"),\n });\n }\n\n if (\n !isRecord(parsed) ||\n parsed.type !== \"AdaptiveCard\" ||\n typeof parsed.version !== \"string\"\n ) {\n throw new Error(\"Invalid Adaptive Card for --card flag\", {\n cause: new Error(\n 'Provide a JSON object with \"type\": \"AdaptiveCard\" and a version',\n ),\n });\n }\n\n return parsed as TeamsCardInput;\n}\n\nexport const sendCommand = new Command()\n .name(\"send\")\n .description(\"Send a message to a Microsoft Teams conversation or DM a user\")\n .option(\"-c, --conversation-id <id>\", \"Teams conversation ID\")\n .option(\"-u, --user <id>\", 'Teams user ID for DM (use \"me\" for yourself)')\n .option(\"-t, --text <message>\", \"Message text\")\n .option(\"--activity-id <id>\", \"Activity ID to reply to\")\n .option(\"--thread <id>\", \"Alias for --activity-id\")\n .option(\"--card <json>\", \"Adaptive Card JSON string\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Simple message: zero teams message send -c 19:thread@thread.tacv2 -t \"Hello!\"\n DM a user: zero teams message send -u 29:user-id -t \"Hello!\"\n DM yourself: zero teams message send -u me -t \"Hello!\"\n Thread reply: zero teams message send -c 19:thread@thread.tacv2 --thread root-activity -t \"reply\"\n Adaptive Card: zero teams message send -c 19:thread@thread.tacv2 --card '{\"type\":\"AdaptiveCard\",\"version\":\"1.4\",\"body\":[{\"type\":\"TextBlock\",\"text\":\"Hello\",\"wrap\":true}]}'\n\nNotes:\n - Either --conversation-id or --user is required; they are mutually exclusive\n - Either --text or --card is required; text can be provided with --text or piped on stdin\n - Use the Conversation ID and Activity ID from the current Teams run prompt`,\n )\n .action(\n withErrorHandler(\n async (options: {\n conversationId?: string;\n user?: string;\n text?: string;\n activityId?: string;\n thread?: string;\n card?: string;\n }) => {\n let text = options.text;\n const { conversationId, user, card: cardJson } = options;\n\n if (!conversationId && !user) {\n throw new Error(\n \"Either --conversation-id or --user must be provided\",\n {\n cause: new Error(\n 'Usage: zero teams message send -c CONVERSATION_ID -t \"your message\"\\n zero teams message send -u USER_ID -t \"your message\"',\n ),\n },\n );\n }\n if (conversationId && user) {\n throw new Error(\n \"--conversation-id and --user are mutually exclusive\",\n {\n cause: new Error(\n \"Provide either --conversation-id to send to a conversation or --user to DM a user, not both\",\n ),\n },\n );\n }\n\n const activityId = options.activityId ?? options.thread;\n if (user && activityId) {\n throw new Error(\n \"--activity-id and --thread can only be used with --conversation-id\",\n {\n cause: new Error(\n \"Thread replies require an existing Teams conversation\",\n ),\n },\n );\n }\n\n if (!text && !process.stdin.isTTY) {\n try {\n text = readFileSync(\"/dev/stdin\", \"utf8\").trim();\n } catch {\n // stdin not readable; fall through to the missing-text validation.\n }\n }\n\n const card = cardJson ? parseTeamsCard(cardJson) : undefined;\n\n if (!text && !card) {\n throw new Error(\n \"Either --text, --card, or piped stdin must be provided\",\n {\n cause: new Error(\n 'Usage: zero teams message send -c CONVERSATION_ID -t \"your message\"',\n ),\n },\n );\n }\n\n const body: SendTeamsMessageBody = {\n ...(conversationId ? { conversationId } : { user }),\n ...(activityId ? { activityId } : {}),\n ...(text ? { text } : {}),\n ...(card ? { card } : {}),\n };\n const result = await sendTeamsMessage({\n ...body,\n });\n\n const activityInfo = result.activityId\n ? ` (activity_id: ${result.activityId})`\n : \"\";\n console.log(chalk.green(`✓ Message sent${activityInfo}`));\n },\n ),\n );\n","import { readFileSync, statSync } from \"fs\";\nimport { basename, extname } from \"path\";\nimport { Command } from \"commander\";\nimport { completeTeamsFileUpload, initTeamsFileUpload } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nconst MIME_BY_EXTENSION: Record<string, string> = {\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".mp4\": \"video/mp4\",\n \".webm\": \"video/webm\",\n \".mov\": \"video/quicktime\",\n \".pdf\": \"application/pdf\",\n \".txt\": \"text/plain\",\n \".csv\": \"text/csv\",\n \".md\": \"text/markdown\",\n \".json\": \"application/json\",\n};\n\nfunction inferContentType(localPath: string): string {\n const ext = extname(localPath).toLowerCase();\n return MIME_BY_EXTENSION[ext] ?? \"application/octet-stream\";\n}\n\nexport const uploadFileCommand = new Command()\n .name(\"upload-file\")\n .description(\n \"Upload a local file to a Microsoft Teams conversation as the bot\",\n )\n .requiredOption(\"-f, --file <path>\", \"Local file path to upload\")\n .requiredOption(\"-c, --conversation-id <id>\", \"Teams conversation ID\")\n .option(\"--activity-id <id>\", \"Activity ID to reply to\")\n .option(\"-t, --text <message>\", \"Message text to accompany the file\")\n .option(\"--content-type <mime>\", \"Override inferred content type\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Upload a file: zero teams upload-file -f /tmp/report.pdf -c 19:thread@thread.tacv2\n Upload to thread: zero teams upload-file -f /tmp/log.txt -c 19:thread@thread.tacv2 --activity-id root-activity\n With message text: zero teams upload-file -f /tmp/data.csv -c 19:thread@thread.tacv2 -t \"Daily report\"\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"activityId\":\"...\",\"conversationId\":\"19:...\",\"filename\":\"report.pdf\",\"mimetype\":\"application/pdf\",\"size\":12345,\"url\":\"https://...\"}\n\nNotes:\n - Uploads through VM0 storage first, then sends the Teams message with the file URL\n - Use the Conversation ID and Activity ID from the current Teams run prompt`,\n )\n .action(\n withErrorHandler(\n async (options: {\n file: string;\n conversationId: string;\n activityId?: string;\n text?: string;\n contentType?: string;\n }) => {\n let fileSize: number;\n try {\n const stat = statSync(options.file);\n if (!stat.isFile()) {\n throw new Error(`Not a regular file: ${options.file}`);\n }\n fileSize = stat.size;\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"Not \")) {\n throw error;\n }\n throw new Error(`File not found: ${options.file}`);\n }\n\n if (fileSize === 0) {\n throw new Error(\"File is empty\");\n }\n\n const filename = basename(options.file);\n const contentType =\n options.contentType ?? inferContentType(options.file);\n const prepared = await initTeamsFileUpload({\n filename,\n contentType,\n length: fileSize,\n });\n\n const fileContent = readFileSync(options.file);\n const uploadResponse = await fetch(prepared.uploadUrl, {\n method: \"PUT\",\n headers: { \"Content-Type\": prepared.contentType },\n body: new Uint8Array(fileContent),\n });\n\n if (!uploadResponse.ok) {\n throw new Error(\n `File upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`,\n );\n }\n\n const result = await completeTeamsFileUpload({\n uploadId: prepared.uploadId,\n conversationId: options.conversationId,\n activityId: options.activityId,\n contentType: prepared.contentType,\n text: options.text,\n });\n\n console.log(JSON.stringify(result));\n },\n ),\n );\n","import { basename, join } from \"path\";\nimport { tmpdir } from \"os\";\nimport { Command } from \"commander\";\nimport { downloadTeamsFile } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nfunction defaultOutPath(fileId: string): string {\n return join(tmpdir(), `teams-${basename(fileId).slice(0, 48)}`);\n}\n\nexport const downloadFileCommand = new Command()\n .name(\"download-file\")\n .description(\"Download a Microsoft Teams file by signed file id\")\n .argument(\"<file-id>\", \"Microsoft Teams file id from a [Teams file] block\")\n .option(\n \"-o, --out <path>\",\n \"Output path for the downloaded file (default: /tmp/teams-<file-id>)\",\n )\n .addHelpText(\n \"after\",\n `\nExamples:\n Download to default temp path: zero teams download-file <file-id>\n Download to explicit path: zero teams download-file <file-id> -o /tmp/file.png\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"path\":\"/tmp/teams-...\",\"mimetype\":\"image/png\",\"size\":12345}\n\nNotes:\n - Use the file id from a [Teams file] block in the prompt\n - Streams the file bytes directly to disk`,\n )\n .action(\n withErrorHandler(async (fileId: string, options: { out?: string }) => {\n const outPath = options.out ?? defaultOutPath(fileId);\n const result = await downloadTeamsFile(fileId, outPath);\n console.log(JSON.stringify(result));\n }),\n );\n"],"mappings":"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","names":["readFileSync","readFileSync","basename","basename"]}
1
+ {"version":3,"sources":["../src/commands/zero/teams/index.ts","../src/commands/zero/teams/message/index.ts","../src/commands/zero/teams/message/send.ts","../src/commands/zero/teams/upload-file.ts","../src/commands/zero/teams/download-file.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { zeroTeamsMessageCommand } from \"./message\";\nimport { uploadFileCommand } from \"./upload-file\";\nimport { downloadFileCommand } from \"./download-file\";\n\nexport const zeroTeamsCommand = new Command()\n .name(\"teams\")\n .description(\n \"Send messages, upload files, and download files from Microsoft Teams as the bot\",\n )\n .addCommand(zeroTeamsMessageCommand)\n .addCommand(uploadFileCommand)\n .addCommand(downloadFileCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n Send a message: zero teams message send -c <conversation-id> -t \"Hello!\"\n DM a user: zero teams message send -u me -t \"Hello!\"\n Reply in a thread: zero teams message send -c <conversation-id> --thread <activity-id> -t \"reply\"\n Upload a file: zero teams upload-file -f /tmp/report.pdf -c <conversation-id>\n Download a file: zero teams download-file <file-id> -o /tmp/out.png`,\n );\n","import { Command } from \"commander\";\nimport { sendCommand } from \"./send\";\n\nexport const zeroTeamsMessageCommand = new Command()\n .name(\"message\")\n .description(\"Manage Microsoft Teams messages\")\n .addCommand(sendCommand)\n .addHelpText(\n \"after\",\n `\nExamples:\n zero teams message send -c <conversation-id> -t \"Hello!\"\n zero teams message send -u me -t \"Hello!\"`,\n );\n","import { readFileSync } from \"fs\";\nimport { Command } from \"commander\";\nimport type { SendTeamsMessageBody } from \"@vm0/api-contracts/contracts/integrations\";\nimport chalk from \"chalk\";\nimport { sendTeamsMessage } from \"../../../../lib/api\";\nimport { withErrorHandler } from \"../../../../lib/command\";\n\ntype TeamsCardInput = NonNullable<SendTeamsMessageBody[\"card\"]>;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction parseTeamsCard(value: string): TeamsCardInput {\n let parsed: unknown;\n try {\n parsed = JSON.parse(value);\n } catch {\n throw new Error(\"Invalid JSON for --card flag\", {\n cause: new Error(\"Provide a valid Adaptive Card JSON object\"),\n });\n }\n\n if (\n !isRecord(parsed) ||\n parsed.type !== \"AdaptiveCard\" ||\n typeof parsed.version !== \"string\"\n ) {\n throw new Error(\"Invalid Adaptive Card for --card flag\", {\n cause: new Error(\n 'Provide a JSON object with \"type\": \"AdaptiveCard\" and a version',\n ),\n });\n }\n\n return parsed as TeamsCardInput;\n}\n\nexport const sendCommand = new Command()\n .name(\"send\")\n .description(\"Send a message to a Microsoft Teams conversation or DM a user\")\n .option(\"-c, --conversation-id <id>\", \"Teams conversation ID\")\n .option(\"-u, --user <id>\", 'Teams user ID for DM (use \"me\" for yourself)')\n .option(\"-t, --text <message>\", \"Message text\")\n .option(\"--activity-id <id>\", \"Activity ID to reply to\")\n .option(\"--thread <id>\", \"Alias for --activity-id\")\n .option(\"--card <json>\", \"Adaptive Card JSON string\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Simple message: zero teams message send -c 19:thread@thread.tacv2 -t \"Hello!\"\n DM a user: zero teams message send -u 29:user-id -t \"Hello!\"\n DM yourself: zero teams message send -u me -t \"Hello!\"\n Thread reply: zero teams message send -c 19:thread@thread.tacv2 --thread root-activity -t \"reply\"\n Adaptive Card: zero teams message send -c 19:thread@thread.tacv2 --card '{\"type\":\"AdaptiveCard\",\"version\":\"1.4\",\"body\":[{\"type\":\"TextBlock\",\"text\":\"Hello\",\"wrap\":true}]}'\n\nNotes:\n - Either --conversation-id or --user is required; they are mutually exclusive\n - Either --text or --card is required; text can be provided with --text or piped on stdin\n - Use the Conversation ID and Activity ID from the current Teams run prompt`,\n )\n .action(\n withErrorHandler(\n async (options: {\n conversationId?: string;\n user?: string;\n text?: string;\n activityId?: string;\n thread?: string;\n card?: string;\n }) => {\n let text = options.text;\n const { conversationId, user, card: cardJson } = options;\n\n if (!conversationId && !user) {\n throw new Error(\n \"Either --conversation-id or --user must be provided\",\n {\n cause: new Error(\n 'Usage: zero teams message send -c CONVERSATION_ID -t \"your message\"\\n zero teams message send -u USER_ID -t \"your message\"',\n ),\n },\n );\n }\n if (conversationId && user) {\n throw new Error(\n \"--conversation-id and --user are mutually exclusive\",\n {\n cause: new Error(\n \"Provide either --conversation-id to send to a conversation or --user to DM a user, not both\",\n ),\n },\n );\n }\n\n const activityId = options.activityId ?? options.thread;\n if (user && activityId) {\n throw new Error(\n \"--activity-id and --thread can only be used with --conversation-id\",\n {\n cause: new Error(\n \"Thread replies require an existing Teams conversation\",\n ),\n },\n );\n }\n\n if (!text && !process.stdin.isTTY) {\n try {\n text = readFileSync(\"/dev/stdin\", \"utf8\").trim();\n } catch {\n // stdin not readable; fall through to the missing-text validation.\n }\n }\n\n const card = cardJson ? parseTeamsCard(cardJson) : undefined;\n\n if (!text && !card) {\n throw new Error(\n \"Either --text, --card, or piped stdin must be provided\",\n {\n cause: new Error(\n 'Usage: zero teams message send -c CONVERSATION_ID -t \"your message\"',\n ),\n },\n );\n }\n\n const body: SendTeamsMessageBody = {\n ...(conversationId ? { conversationId } : { user }),\n ...(activityId ? { activityId } : {}),\n ...(text ? { text } : {}),\n ...(card ? { card } : {}),\n };\n const result = await sendTeamsMessage({\n ...body,\n });\n\n const activityInfo = result.activityId\n ? ` (activity_id: ${result.activityId})`\n : \"\";\n console.log(chalk.green(`✓ Message sent${activityInfo}`));\n },\n ),\n );\n","import { readFileSync, statSync } from \"fs\";\nimport { basename, extname } from \"path\";\nimport { Command } from \"commander\";\nimport { completeTeamsFileUpload, initTeamsFileUpload } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nconst MIME_BY_EXTENSION: Record<string, string> = {\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".mp4\": \"video/mp4\",\n \".webm\": \"video/webm\",\n \".mov\": \"video/quicktime\",\n \".pdf\": \"application/pdf\",\n \".txt\": \"text/plain\",\n \".csv\": \"text/csv\",\n \".md\": \"text/markdown\",\n \".json\": \"application/json\",\n};\n\nfunction inferContentType(localPath: string): string {\n const ext = extname(localPath).toLowerCase();\n return MIME_BY_EXTENSION[ext] ?? \"application/octet-stream\";\n}\n\nexport const uploadFileCommand = new Command()\n .name(\"upload-file\")\n .description(\n \"Upload a local file to a Microsoft Teams conversation as the bot\",\n )\n .requiredOption(\"-f, --file <path>\", \"Local file path to upload\")\n .requiredOption(\"-c, --conversation-id <id>\", \"Teams conversation ID\")\n .option(\"--activity-id <id>\", \"Activity ID to reply to\")\n .option(\"-t, --text <message>\", \"Message text to accompany the file\")\n .option(\"--content-type <mime>\", \"Override inferred content type\")\n .addHelpText(\n \"after\",\n `\nExamples:\n Upload a file: zero teams upload-file -f /tmp/report.pdf -c 19:thread@thread.tacv2\n Upload to thread: zero teams upload-file -f /tmp/log.txt -c 19:thread@thread.tacv2 --activity-id root-activity\n With message text: zero teams upload-file -f /tmp/data.csv -c 19:thread@thread.tacv2 -t \"Daily report\"\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"activityId\":\"...\",\"conversationId\":\"19:...\",\"filename\":\"report.pdf\",\"mimetype\":\"application/pdf\",\"size\":12345,\"url\":\"https://...\"}\n\nNotes:\n - Uploads through VM0 storage first, then sends the Teams message with the file URL\n - Use the Conversation ID and Activity ID from the current Teams run prompt`,\n )\n .action(\n withErrorHandler(\n async (options: {\n file: string;\n conversationId: string;\n activityId?: string;\n text?: string;\n contentType?: string;\n }) => {\n let fileSize: number;\n try {\n const stat = statSync(options.file);\n if (!stat.isFile()) {\n throw new Error(`Not a regular file: ${options.file}`);\n }\n fileSize = stat.size;\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"Not \")) {\n throw error;\n }\n throw new Error(`File not found: ${options.file}`);\n }\n\n if (fileSize === 0) {\n throw new Error(\"File is empty\");\n }\n\n const filename = basename(options.file);\n const contentType =\n options.contentType ?? inferContentType(options.file);\n const prepared = await initTeamsFileUpload({\n filename,\n contentType,\n length: fileSize,\n supportsUploadHeaders: true,\n });\n\n const fileContent = readFileSync(options.file);\n const uploadResponse = await fetch(prepared.uploadUrl, {\n method: \"PUT\",\n headers: {\n \"Content-Type\": prepared.contentType,\n ...prepared.uploadHeaders,\n },\n body: new Uint8Array(fileContent),\n });\n\n if (!uploadResponse.ok) {\n throw new Error(\n `File upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`,\n );\n }\n\n const result = await completeTeamsFileUpload({\n uploadId: prepared.uploadId,\n conversationId: options.conversationId,\n activityId: options.activityId,\n contentType: prepared.contentType,\n text: options.text,\n });\n\n console.log(JSON.stringify(result));\n },\n ),\n );\n","import { basename, join } from \"path\";\nimport { tmpdir } from \"os\";\nimport { Command } from \"commander\";\nimport { downloadTeamsFile } from \"../../../lib/api\";\nimport { withErrorHandler } from \"../../../lib/command\";\n\nfunction defaultOutPath(fileId: string): string {\n return join(tmpdir(), `teams-${basename(fileId).slice(0, 48)}`);\n}\n\nexport const downloadFileCommand = new Command()\n .name(\"download-file\")\n .description(\"Download a Microsoft Teams file by signed file id\")\n .argument(\"<file-id>\", \"Microsoft Teams file id from a [Teams file] block\")\n .option(\n \"-o, --out <path>\",\n \"Output path for the downloaded file (default: /tmp/teams-<file-id>)\",\n )\n .addHelpText(\n \"after\",\n `\nExamples:\n Download to default temp path: zero teams download-file <file-id>\n Download to explicit path: zero teams download-file <file-id> -o /tmp/file.png\n\nOutput:\n Prints a JSON object to stdout on success:\n {\"path\":\"/tmp/teams-...\",\"mimetype\":\"image/png\",\"size\":12345}\n\nNotes:\n - Use the file id from a [Teams file] block in the prompt\n - Streams the file bytes directly to disk`,\n )\n .action(\n withErrorHandler(async (fileId: string, options: { out?: string }) => {\n const outPath = options.out ?? defaultOutPath(fileId);\n const result = await downloadTeamsFile(fileId, outPath);\n console.log(JSON.stringify(result));\n }),\n );\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;ACAA;;;ACAA;AAAA,SAAS,oBAAoB;AAS7B,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,eAAe,OAA+B;AACrD,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,KAAK;AAAA,EAC3B,QAAQ;AACN,UAAM,IAAI,MAAM,gCAAgC;AAAA,MAC9C,OAAO,IAAI,MAAM,2CAA2C;AAAA,IAC9D,CAAC;AAAA,EACH;AAEA,MACE,CAAC,SAAS,MAAM,KAChB,OAAO,SAAS,kBAChB,OAAO,OAAO,YAAY,UAC1B;AACA,UAAM,IAAI,MAAM,yCAAyC;AAAA,MACvD,OAAO,IAAI;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEO,IAAM,cAAc,IAAI,QAAQ,EACpC,KAAK,MAAM,EACX,YAAY,+DAA+D,EAC3E,OAAO,8BAA8B,uBAAuB,EAC5D,OAAO,mBAAmB,8CAA8C,EACxE,OAAO,wBAAwB,cAAc,EAC7C,OAAO,sBAAsB,yBAAyB,EACtD,OAAO,iBAAiB,yBAAyB,EACjD,OAAO,iBAAiB,2BAA2B,EACnD;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYF,EACC;AAAA,EACC;AAAA,IACE,OAAO,YAOD;AACJ,UAAI,OAAO,QAAQ;AACnB,YAAM,EAAE,gBAAgB,MAAM,MAAM,SAAS,IAAI;AAEjD,UAAI,CAAC,kBAAkB,CAAC,MAAM;AAC5B,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,YACE,OAAO,IAAI;AAAA,cACT;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,UAAI,kBAAkB,MAAM;AAC1B,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,YACE,OAAO,IAAI;AAAA,cACT;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,aAAa,QAAQ,cAAc,QAAQ;AACjD,UAAI,QAAQ,YAAY;AACtB,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,YACE,OAAO,IAAI;AAAA,cACT;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,UAAI,CAAC,QAAQ,CAAC,QAAQ,MAAM,OAAO;AACjC,YAAI;AACF,iBAAO,aAAa,cAAc,MAAM,EAAE,KAAK;AAAA,QACjD,QAAQ;AAAA,QAER;AAAA,MACF;AAEA,YAAM,OAAO,WAAW,eAAe,QAAQ,IAAI;AAEnD,UAAI,CAAC,QAAQ,CAAC,MAAM;AAClB,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,YACE,OAAO,IAAI;AAAA,cACT;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,OAA6B;AAAA,QACjC,GAAI,iBAAiB,EAAE,eAAe,IAAI,EAAE,KAAK;AAAA,QACjD,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,QACnC,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,QACvB,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,MACzB;AACA,YAAM,SAAS,MAAM,iBAAiB;AAAA,QACpC,GAAG;AAAA,MACL,CAAC;AAED,YAAM,eAAe,OAAO,aACxB,kBAAkB,OAAO,UAAU,MACnC;AACJ,cAAQ,IAAI,eAAM,MAAM,sBAAiB,YAAY,EAAE,CAAC;AAAA,IAC1D;AAAA,EACF;AACF;;;AD9IK,IAAM,0BAA0B,IAAI,QAAQ,EAChD,KAAK,SAAS,EACd,YAAY,iCAAiC,EAC7C,WAAW,WAAW,EACtB;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAIF;;;AEbF;AAAA,SAAS,gBAAAA,eAAc,gBAAgB;AACvC,SAAS,UAAU,eAAe;AAKlC,IAAM,oBAA4C;AAAA,EAChD,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AACX;AAEA,SAAS,iBAAiB,WAA2B;AACnD,QAAM,MAAM,QAAQ,SAAS,EAAE,YAAY;AAC3C,SAAO,kBAAkB,GAAG,KAAK;AACnC;AAEO,IAAM,oBAAoB,IAAI,QAAQ,EAC1C,KAAK,aAAa,EAClB;AAAA,EACC;AACF,EACC,eAAe,qBAAqB,2BAA2B,EAC/D,eAAe,8BAA8B,uBAAuB,EACpE,OAAO,sBAAsB,yBAAyB,EACtD,OAAO,wBAAwB,oCAAoC,EACnE,OAAO,yBAAyB,gCAAgC,EAChE;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaF,EACC;AAAA,EACC;AAAA,IACE,OAAO,YAMD;AACJ,UAAI;AACJ,UAAI;AACF,cAAM,OAAO,SAAS,QAAQ,IAAI;AAClC,YAAI,CAAC,KAAK,OAAO,GAAG;AAClB,gBAAM,IAAI,MAAM,uBAAuB,QAAQ,IAAI,EAAE;AAAA,QACvD;AACA,mBAAW,KAAK;AAAA,MAClB,SAAS,OAAO;AACd,YAAI,iBAAiB,SAAS,MAAM,QAAQ,WAAW,MAAM,GAAG;AAC9D,gBAAM;AAAA,QACR;AACA,cAAM,IAAI,MAAM,mBAAmB,QAAQ,IAAI,EAAE;AAAA,MACnD;AAEA,UAAI,aAAa,GAAG;AAClB,cAAM,IAAI,MAAM,eAAe;AAAA,MACjC;AAEA,YAAM,WAAW,SAAS,QAAQ,IAAI;AACtC,YAAM,cACJ,QAAQ,eAAe,iBAAiB,QAAQ,IAAI;AACtD,YAAM,WAAW,MAAM,oBAAoB;AAAA,QACzC;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,uBAAuB;AAAA,MACzB,CAAC;AAED,YAAM,cAAcC,cAAa,QAAQ,IAAI;AAC7C,YAAM,iBAAiB,MAAM,MAAM,SAAS,WAAW;AAAA,QACrD,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB,SAAS;AAAA,UACzB,GAAG,SAAS;AAAA,QACd;AAAA,QACA,MAAM,IAAI,WAAW,WAAW;AAAA,MAClC,CAAC;AAED,UAAI,CAAC,eAAe,IAAI;AACtB,cAAM,IAAI;AAAA,UACR,uBAAuB,eAAe,MAAM,IAAI,eAAe,UAAU;AAAA,QAC3E;AAAA,MACF;AAEA,YAAM,SAAS,MAAM,wBAAwB;AAAA,QAC3C,UAAU,SAAS;AAAA,QACnB,gBAAgB,QAAQ;AAAA,QACxB,YAAY,QAAQ;AAAA,QACpB,aAAa,SAAS;AAAA,QACtB,MAAM,QAAQ;AAAA,MAChB,CAAC;AAED,cAAQ,IAAI,KAAK,UAAU,MAAM,CAAC;AAAA,IACpC;AAAA,EACF;AACF;;;ACtHF;AAAA,SAAS,YAAAC,WAAU,YAAY;AAC/B,SAAS,cAAc;AAKvB,SAAS,eAAe,QAAwB;AAC9C,SAAO,KAAK,OAAO,GAAG,SAASC,UAAS,MAAM,EAAE,MAAM,GAAG,EAAE,CAAC,EAAE;AAChE;AAEO,IAAM,sBAAsB,IAAI,QAAQ,EAC5C,KAAK,eAAe,EACpB,YAAY,mDAAmD,EAC/D,SAAS,aAAa,mDAAmD,EACzE;AAAA,EACC;AAAA,EACA;AACF,EACC;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYF,EACC;AAAA,EACC,iBAAiB,OAAO,QAAgB,YAA8B;AACpE,UAAM,UAAU,QAAQ,OAAO,eAAe,MAAM;AACpD,UAAM,SAAS,MAAM,kBAAkB,QAAQ,OAAO;AACtD,YAAQ,IAAI,KAAK,UAAU,MAAM,CAAC;AAAA,EACpC,CAAC;AACH;;;AJlCK,IAAM,mBAAmB,IAAI,QAAQ,EACzC,KAAK,OAAO,EACZ;AAAA,EACC;AACF,EACC,WAAW,uBAAuB,EAClC,WAAW,iBAAiB,EAC5B,WAAW,mBAAmB,EAC9B;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOF;","names":["readFileSync","readFileSync","basename","basename"]}
@@ -7,14 +7,14 @@ import {
7
7
  initTelegramFileUpload,
8
8
  listTelegramBots,
9
9
  sendTelegramMessage
10
- } from "./chunk-NGVPA5PP.js";
11
- import "./chunk-72ZGOFYI.js";
10
+ } from "./chunk-TZDXFY6G.js";
11
+ import "./chunk-JXUQQIUP.js";
12
12
  import "./chunk-MA22KQYU.js";
13
13
  import {
14
14
  source_default,
15
15
  withErrorHandler
16
- } from "./chunk-JUE2IIB6.js";
17
- import "./chunk-ZUHSC7WF.js";
16
+ } from "./chunk-D7TEG7WN.js";
17
+ import "./chunk-MD3YWUKO.js";
18
18
  import {
19
19
  Command
20
20
  } from "./chunk-CCWPKGTB.js";
@@ -293,12 +293,16 @@ Notes:
293
293
  const prepared = await initTelegramFileUpload({
294
294
  filename,
295
295
  contentType,
296
- length: fileSize
296
+ length: fileSize,
297
+ supportsUploadHeaders: true
297
298
  });
298
299
  const fileContent = readFileSync2(options.file);
299
300
  const uploadResponse = await fetch(prepared.uploadUrl, {
300
301
  method: "PUT",
301
- headers: { "Content-Type": prepared.contentType },
302
+ headers: {
303
+ "Content-Type": prepared.contentType,
304
+ ...prepared.uploadHeaders
305
+ },
302
306
  body: new Uint8Array(fileContent)
303
307
  });
304
308
  if (!uploadResponse.ok) {
@@ -334,4 +338,4 @@ Examples:
334
338
  export {
335
339
  zeroTelegramCommand
336
340
  };
337
- //# sourceMappingURL=telegram-AC6MPDBH.js.map
341
+ //# sourceMappingURL=telegram-2E2UM67J.js.map