@wirecat/zoom-cli 0.3.2 → 0.5.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 (99) hide show
  1. package/README.md +109 -7
  2. package/dist/archive-commands.d.ts +2 -1
  3. package/dist/archive-commands.d.ts.map +1 -1
  4. package/dist/archive-commands.js +54 -10
  5. package/dist/archive-commands.js.map +1 -1
  6. package/dist/archive-import.d.ts +6 -2
  7. package/dist/archive-import.d.ts.map +1 -1
  8. package/dist/archive-import.js +32 -8
  9. package/dist/archive-import.js.map +1 -1
  10. package/dist/bin/zm.js +2 -0
  11. package/dist/bin/zm.js.map +1 -1
  12. package/dist/execution.d.ts.map +1 -1
  13. package/dist/execution.js +4 -0
  14. package/dist/execution.js.map +1 -1
  15. package/dist/index.d.ts +7 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +5 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/local-transcription-commands.d.ts +9 -0
  20. package/dist/local-transcription-commands.d.ts.map +1 -0
  21. package/dist/local-transcription-commands.js +51 -0
  22. package/dist/local-transcription-commands.js.map +1 -0
  23. package/dist/local-transcription.d.ts +52 -0
  24. package/dist/local-transcription.d.ts.map +1 -0
  25. package/dist/local-transcription.js +161 -0
  26. package/dist/local-transcription.js.map +1 -0
  27. package/dist/meeting-integration-commands.d.ts +9 -0
  28. package/dist/meeting-integration-commands.d.ts.map +1 -0
  29. package/dist/meeting-integration-commands.js +64 -0
  30. package/dist/meeting-integration-commands.js.map +1 -0
  31. package/dist/meeting-integration.d.ts +12 -0
  32. package/dist/meeting-integration.d.ts.map +1 -0
  33. package/dist/meeting-integration.js +9 -0
  34. package/dist/meeting-integration.js.map +1 -0
  35. package/dist/meeting-search-commands.d.ts +33 -0
  36. package/dist/meeting-search-commands.d.ts.map +1 -0
  37. package/dist/meeting-search-commands.js +85 -0
  38. package/dist/meeting-search-commands.js.map +1 -0
  39. package/dist/ordinary-file.d.ts +1 -0
  40. package/dist/ordinary-file.d.ts.map +1 -1
  41. package/dist/ordinary-file.js +13 -0
  42. package/dist/ordinary-file.js.map +1 -1
  43. package/dist/program.d.ts +22 -4
  44. package/dist/program.d.ts.map +1 -1
  45. package/dist/program.js +155 -4
  46. package/dist/program.js.map +1 -1
  47. package/dist/recording-archive.d.ts +2 -0
  48. package/dist/recording-archive.d.ts.map +1 -1
  49. package/dist/recording-archive.js +151 -79
  50. package/dist/recording-archive.js.map +1 -1
  51. package/dist/recording-partial-store.d.ts +20 -0
  52. package/dist/recording-partial-store.d.ts.map +1 -0
  53. package/dist/recording-partial-store.js +225 -0
  54. package/dist/recording-partial-store.js.map +1 -0
  55. package/dist/recording-promotion-store.d.ts +12 -0
  56. package/dist/recording-promotion-store.d.ts.map +1 -0
  57. package/dist/recording-promotion-store.js +92 -0
  58. package/dist/recording-promotion-store.js.map +1 -0
  59. package/dist/recording-schedule-commands.d.ts +12 -0
  60. package/dist/recording-schedule-commands.d.ts.map +1 -0
  61. package/dist/recording-schedule-commands.js +80 -0
  62. package/dist/recording-schedule-commands.js.map +1 -0
  63. package/dist/recording-schedule-store.d.ts +4 -0
  64. package/dist/recording-schedule-store.d.ts.map +1 -0
  65. package/dist/recording-schedule-store.js +141 -0
  66. package/dist/recording-schedule-store.js.map +1 -0
  67. package/dist/recording-schedule-systemd.d.ts +14 -0
  68. package/dist/recording-schedule-systemd.d.ts.map +1 -0
  69. package/dist/recording-schedule-systemd.js +173 -0
  70. package/dist/recording-schedule-systemd.js.map +1 -0
  71. package/dist/recording-schedule.d.ts +93 -0
  72. package/dist/recording-schedule.d.ts.map +1 -0
  73. package/dist/recording-schedule.js +121 -0
  74. package/dist/recording-schedule.js.map +1 -0
  75. package/dist/recording-sync-store.d.ts +3 -0
  76. package/dist/recording-sync-store.d.ts.map +1 -0
  77. package/dist/recording-sync-store.js +187 -0
  78. package/dist/recording-sync-store.js.map +1 -0
  79. package/dist/recording-sync.d.ts +10 -1
  80. package/dist/recording-sync.d.ts.map +1 -1
  81. package/dist/recording-sync.js +72 -41
  82. package/dist/recording-sync.js.map +1 -1
  83. package/dist/recordings.d.ts +9 -10
  84. package/dist/recordings.d.ts.map +1 -1
  85. package/dist/recordings.js +50 -13
  86. package/dist/recordings.js.map +1 -1
  87. package/dist/remote-meetings.d.ts +15 -0
  88. package/dist/remote-meetings.d.ts.map +1 -1
  89. package/dist/remote-meetings.js +73 -65
  90. package/dist/remote-meetings.js.map +1 -1
  91. package/dist/store-connection.d.ts +5 -1
  92. package/dist/store-connection.d.ts.map +1 -1
  93. package/dist/store-connection.js +145 -9
  94. package/dist/store-connection.js.map +1 -1
  95. package/dist/wav-audio.d.ts +28 -0
  96. package/dist/wav-audio.d.ts.map +1 -0
  97. package/dist/wav-audio.js +191 -0
  98. package/dist/wav-audio.js.map +1 -0
  99. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -4,14 +4,18 @@ export { readArchiveTranscripts, searchArchiveTranscripts, } from "./archive-tra
4
4
  export { profileAccountKey, readConfig, setConfig } from "./config.js";
5
5
  export { ZoomError } from "./errors.js";
6
6
  export { FilesSource, fileMeeting, importFile, readDownloadedFiles, validateDownloadedFiles, } from "./files.js";
7
+ export { createLocalTranscriptionCapabilities, createWavTranscriptionSource, } from "./local-transcription.js";
7
8
  export { login, REDIRECT } from "./login.js";
8
9
  export { createMeetingMcpServer, serveMeetingMcp } from "./mcp-server.js";
9
10
  export { createMeetingContextCapabilities, } from "./meeting-context.js";
10
11
  export { createMeetingSemanticCapabilities } from "./meeting-semantic.js";
11
12
  export { createProgram, run } from "./program.js";
13
+ export { createRecordingScheduleService, parseRecordingScheduleJob, snapshotRecordingScheduleCapture, validateRecordingScheduleId, } from "./recording-schedule.js";
14
+ export { fileRecordingScheduleStore } from "./recording-schedule-store.js";
15
+ export { createSystemdRecordingArchiveScheduler } from "./recording-schedule-systemd.js";
12
16
  export { syncRecordingArchive } from "./recording-sync.js";
13
17
  export { getZoomProfile, inspectArchive, inspectArchiveLocks, recoverArchiveLocks, verifyArchive, ZoomRecordings, } from "./recordings.js";
14
- export { ZoomRemoteMeetings, } from "./remote-meetings.js";
18
+ export { createZoomMeetingManagement, ZoomRemoteMeetings, } from "./remote-meetings.js";
15
19
  export { createStoreConnector } from "./store-connection.js";
16
20
  export { TokenManager } from "./tokens.js";
17
21
  export { runUnifiedSearch } from "./unified-search.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAIL,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAML,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAmB,MAAM,aAAa,CAAA;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAEL,WAAW,EACX,WAAW,EACX,UAAU,EACV,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAqB,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,EAAE,sBAAsB,EAA0B,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjG,OAAO,EACL,gCAAgC,GAKjC,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAA;AAOzE,OAAO,EAAE,aAAa,EAAoB,GAAG,EAAkD,MAAM,cAAc,CAAA;AACnH,OAAO,EAAoD,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC5G,OAAO,EAOL,cAAc,EACd,cAAc,EACd,mBAAmB,EAInB,mBAAmB,EACnB,aAAa,EAEb,cAAc,GACf,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAKL,kBAAkB,GACnB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,oBAAoB,EAA+B,MAAM,uBAAuB,CAAA;AACzF,OAAO,EAAE,YAAY,EAAkC,MAAM,aAAa,CAAA;AAE1E,OAAO,EAAE,gBAAgB,EAAiD,MAAM,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAIL,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAML,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAmB,MAAM,aAAa,CAAA;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAEL,WAAW,EACX,WAAW,EACX,UAAU,EACV,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,oCAAoC,EACpC,4BAA4B,GAK7B,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAqB,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC/D,OAAO,EAAE,sBAAsB,EAA0B,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjG,OAAO,EACL,gCAAgC,GAKjC,MAAM,sBAAsB,CAAA;AAG7B,OAAO,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAA;AAOzE,OAAO,EAAE,aAAa,EAAoB,GAAG,EAAkD,MAAM,cAAc,CAAA;AACnH,OAAO,EACL,8BAA8B,EAC9B,yBAAyB,EASzB,gCAAgC,EAChC,2BAA2B,GAC5B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAA;AAC1E,OAAO,EAAE,sCAAsC,EAAkC,MAAM,iCAAiC,CAAA;AACxH,OAAO,EAAoD,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC5G,OAAO,EAOL,cAAc,EACd,cAAc,EACd,mBAAmB,EAInB,mBAAmB,EACnB,aAAa,EAEb,cAAc,GACf,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,2BAA2B,EAK3B,kBAAkB,GACnB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,oBAAoB,EAA+B,MAAM,uBAAuB,CAAA;AACzF,OAAO,EAAE,YAAY,EAAkC,MAAM,aAAa,CAAA;AAE1E,OAAO,EAAE,gBAAgB,EAAiD,MAAM,qBAAqB,CAAA"}
@@ -0,0 +1,9 @@
1
+ import type { Command } from "commander";
2
+ import { type LocalTranscriptionCapabilities } from "./local-transcription.js";
3
+ export declare const addLocalTranscriptionCommands: (program: Command, deps: {
4
+ capabilities: () => Promise<LocalTranscriptionCapabilities>;
5
+ signal: () => AbortSignal | undefined;
6
+ output: (value: unknown) => void;
7
+ receipt: (value: unknown) => Promise<void>;
8
+ }) => void;
9
+ //# sourceMappingURL=local-transcription-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-transcription-commands.d.ts","sourceRoot":"","sources":["../src/local-transcription-commands.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,OAAO,EAEL,KAAK,8BAA8B,EAGpC,MAAM,0BAA0B,CAAA;AAEjC,eAAO,MAAM,6BAA6B,YAC/B,OAAO,QACV;IACJ,YAAY,EAAE,MAAM,OAAO,CAAC,8BAA8B,CAAC,CAAA;IAC3D,MAAM,EAAE,MAAM,WAAW,GAAG,SAAS,CAAA;IACrC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAChC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3C,KACA,IAsDF,CAAA"}
@@ -0,0 +1,51 @@
1
+ import { annotate } from "@wirecat/cli-core/commands";
2
+ import { speechModel } from "@wirecat/cli-messaging/speech";
3
+ import { ZoomError } from "./errors.js";
4
+ import { bytes, duration } from "./execution.js";
5
+ import { compactLocalTranscriptionReceipt, validateLocalTranscriptionOptions, } from "./local-transcription.js";
6
+ export const addLocalTranscriptionCommands = (program, deps) => {
7
+ const meetings = program.commands.find((command) => command.name() === "meetings");
8
+ if (!meetings)
9
+ throw new ZoomError("configuration_error", "meeting command group is unavailable");
10
+ annotate(meetings
11
+ .command("transcribe")
12
+ .description("preview local PCM WAV transcription; --yes recognizes and appends an independent transcript")
13
+ .argument("<meeting>", "selected-account stored meeting id or meeting reference")
14
+ .argument("<file>", "local PCM16 WAV file (16 or 48 kHz, mono/stereo)")
15
+ .requiredOption("--model <model>", "explicit installed speech model")
16
+ .option("--models-dir <directory>", "shared installed speech-model directory")
17
+ .option("--max-bytes <bytes>", "bounded media input bytes (default 1 GiB)", bytes)
18
+ .option("--max-duration <duration>", "bounded audio duration (default 4h)", duration)
19
+ .option("--max-segments <count>", "recognized segment limit (default 10000)", bytes)
20
+ .option("--max-text-bytes <bytes>", "aggregate transcript text limit (default 4 MiB)", bytes)
21
+ .option("--yes", "recognize locally and append to the existing meeting")
22
+ .option("--dry-run", "preview even when --yes is present")
23
+ .action(async (reference, file, options) => {
24
+ const request = validateLocalTranscriptionOptions({
25
+ model: options.model,
26
+ modelsDirectory: options.modelsDir,
27
+ maxBytes: options.maxBytes,
28
+ maxDurationMs: options.maxDuration,
29
+ maxSegments: options.maxSegments,
30
+ maxTextBytes: options.maxTextBytes,
31
+ apply: options.yes,
32
+ dryRun: options.dryRun,
33
+ signal: deps.signal(),
34
+ });
35
+ speechModel(request.model);
36
+ if (typeof file !== "string" || !file.trim() || file.includes("\0"))
37
+ throw new ZoomError("validation_error", "local audio file is required");
38
+ const capabilities = await deps.capabilities();
39
+ const receipt = await capabilities.transcribe(reference, file, request);
40
+ if (receipt.applied)
41
+ await deps.receipt(compactLocalTranscriptionReceipt(receipt));
42
+ else
43
+ deps.output(receipt);
44
+ }), {
45
+ origin: "handwritten",
46
+ mutates: true,
47
+ local: true,
48
+ examples: ["zm meetings transcribe meeting:3/12 ./AliceExample.wav --model parakeet-v3 --json"],
49
+ });
50
+ };
51
+ //# sourceMappingURL=local-transcription-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-transcription-commands.js","sourceRoot":"","sources":["../src/local-transcription-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EACL,gCAAgC,EAGhC,iCAAiC,GAClC,MAAM,0BAA0B,CAAA;AAEjC,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAC3C,OAAgB,EAChB,IAKC,EACK,EAAE;IACR,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,UAAU,CAAC,CAAA;IAClF,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,SAAS,CAAC,qBAAqB,EAAE,sCAAsC,CAAC,CAAA;IACjG,QAAQ,CACN,QAAQ;SACL,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,CAAC,6FAA6F,CAAC;SAC1G,QAAQ,CAAC,WAAW,EAAE,yDAAyD,CAAC;SAChF,QAAQ,CAAC,QAAQ,EAAE,kDAAkD,CAAC;SACtE,cAAc,CAAC,iBAAiB,EAAE,iCAAiC,CAAC;SACpE,MAAM,CAAC,0BAA0B,EAAE,yCAAyC,CAAC;SAC7E,MAAM,CAAC,qBAAqB,EAAE,2CAA2C,EAAE,KAAK,CAAC;SACjF,MAAM,CAAC,2BAA2B,EAAE,qCAAqC,EAAE,QAAQ,CAAC;SACpF,MAAM,CAAC,wBAAwB,EAAE,0CAA0C,EAAE,KAAK,CAAC;SACnF,MAAM,CAAC,0BAA0B,EAAE,iDAAiD,EAAE,KAAK,CAAC;SAC5F,MAAM,CAAC,OAAO,EAAE,sDAAsD,CAAC;SACvE,MAAM,CAAC,WAAW,EAAE,oCAAoC,CAAC;SACzD,MAAM,CACL,KAAK,EACH,SAAiB,EACjB,IAAY,EACZ,OAIC,EACD,EAAE;QACF,MAAM,OAAO,GAAG,iCAAiC,CAAC;YAChD,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,eAAe,EAAE,OAAO,CAAC,SAAS;YAClC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,aAAa,EAAE,OAAO,CAAC,WAAW;YAClC,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,KAAK,EAAE,OAAO,CAAC,GAAG;YAClB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE;SACtB,CAAC,CAAA;QACF,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC1B,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjE,MAAM,IAAI,SAAS,CAAC,kBAAkB,EAAE,8BAA8B,CAAC,CAAA;QACzE,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;QAC9C,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;QACvE,IAAI,OAAO,CAAC,OAAO;YAAE,MAAM,IAAI,CAAC,OAAO,CAAC,gCAAgC,CAAC,OAAO,CAAC,CAAC,CAAA;;YAC7E,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC3B,CAAC,CACF,EACH;QACE,MAAM,EAAE,aAAa;QACrB,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,IAAI;QACX,QAAQ,EAAE,CAAC,mFAAmF,CAAC;KAChG,CACF,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,52 @@
1
+ import type { MeetingMediaDescriptor, MeetingTranscriptionOptions, MeetingTranscriptionReceipt, MeetingTranscriptionSource, MeetingTranscriptReceiptStore } from "@wirecat/cli-meetings";
2
+ import type { LocalSpeechRecognitionModel, LocalSpeechRecognizer, LocalSpeechRecognizerOptions } from "@wirecat/cli-messaging/speech";
3
+ export interface LocalSpeechPort {
4
+ describe(model: string): Readonly<LocalSpeechRecognitionModel>;
5
+ open(model: string, options: LocalSpeechRecognizerOptions): Promise<LocalSpeechRecognizer>;
6
+ }
7
+ export interface LocalTranscriptionOptions extends MeetingTranscriptionOptions {
8
+ model: string;
9
+ modelsDirectory?: string;
10
+ }
11
+ export interface LocalTranscriptionTarget {
12
+ accountId: number;
13
+ meetingId: number;
14
+ externalId: string;
15
+ }
16
+ export interface LocalTranscriptionCapabilities {
17
+ transcribe(reference: string, file: string, options: LocalTranscriptionOptions): Promise<MeetingTranscriptionReceipt>;
18
+ }
19
+ export declare const validateLocalTranscriptionOptions: (input: LocalTranscriptionOptions) => LocalTranscriptionOptions;
20
+ export declare const compactLocalTranscriptionReceipt: (receipt: MeetingTranscriptionReceipt) => {
21
+ applied: true;
22
+ accountId: number;
23
+ externalId: string;
24
+ meetingId: number;
25
+ created: boolean;
26
+ insertedTranscripts: number;
27
+ replayedTranscripts: number;
28
+ supersededTranscripts: number;
29
+ segments: number;
30
+ mediaSha256: string;
31
+ engine: string;
32
+ model: string;
33
+ modelVersion: string | null;
34
+ timing: "fixed-windows" | "recognition-segments";
35
+ };
36
+ export declare const createWavTranscriptionSource: (file: string, options: {
37
+ model: string;
38
+ modelsDirectory?: string;
39
+ env?: NodeJS.ProcessEnv;
40
+ speech?: () => Promise<LocalSpeechPort>;
41
+ }) => MeetingTranscriptionSource;
42
+ export declare const createLocalTranscriptionCapabilities: (store: {
43
+ accountId: number;
44
+ resolveMeeting(reference: string, signal?: AbortSignal): Promise<LocalTranscriptionTarget | null>;
45
+ appendTranscriptsWithReceipt: MeetingTranscriptReceiptStore["appendTranscriptsWithReceipt"];
46
+ }, input?: {
47
+ env?: NodeJS.ProcessEnv;
48
+ now?: () => number;
49
+ speech?: () => Promise<LocalSpeechPort>;
50
+ }) => LocalTranscriptionCapabilities;
51
+ export type { MeetingMediaDescriptor };
52
+ //# sourceMappingURL=local-transcription.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-transcription.d.ts","sourceRoot":"","sources":["../src/local-transcription.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,EAC1B,6BAA6B,EAC9B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EACV,2BAA2B,EAC3B,qBAAqB,EACrB,4BAA4B,EAC7B,MAAM,+BAA+B,CAAA;AAItC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC,2BAA2B,CAAC,CAAA;IAC9D,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAA;CAC3F;AACD,MAAM,WAAW,yBAA0B,SAAQ,2BAA2B;IAC5E,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AACD,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB;AACD,MAAM,WAAW,8BAA8B;IAC7C,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAA;CACtH;AACD,eAAO,MAAM,iCAAiC,UAAW,yBAAyB,KAAG,yBA6BpF,CAAA;AACD,eAAO,MAAM,gCAAgC,YAAa,2BAA2B;IAKjF,OAAO;IACP,SAAS;IACT,UAAU;IACV,SAAS;IACT,OAAO;IACP,mBAAmB;IACnB,mBAAmB;IACnB,qBAAqB;IACrB,QAAQ;IACR,WAAW;IACX,MAAM;IACN,KAAK;IACL,YAAY;IACZ,MAAM;CAET,CAAA;AAKD,eAAO,MAAM,4BAA4B,SACjC,MAAM,WACH;IACP,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAA;CACxC,KACA,0BAoEF,CAAA;AACD,eAAO,MAAM,oCAAoC,UACxC;IACL,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAAA;IACjG,4BAA4B,EAAE,6BAA6B,CAAC,8BAA8B,CAAC,CAAA;CAC5F,UACM;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAA;CAAE,KAC9F,8BAgDF,CAAA;AACD,YAAY,EAAE,sBAAsB,EAAE,CAAA"}
@@ -0,0 +1,161 @@
1
+ import { isAbsolute } from "node:path";
2
+ import { checkCancelled, ZoomError } from "./errors.js";
3
+ import { openWavAudio, preflightWavAudio } from "./wav-audio.js";
4
+ export const validateLocalTranscriptionOptions = (input) => {
5
+ const options = { ...input };
6
+ if (typeof options.model !== "string" ||
7
+ !options.model.trim() ||
8
+ options.model.length > 200 ||
9
+ /[\0\r\n]/.test(options.model))
10
+ throw new ZoomError("validation_error", "local transcription requires an explicit speech model");
11
+ if (options.modelsDirectory !== undefined &&
12
+ (typeof options.modelsDirectory !== "string" ||
13
+ !isAbsolute(options.modelsDirectory) ||
14
+ options.modelsDirectory.length > 4096 ||
15
+ /[\0\r\n]/.test(options.modelsDirectory)))
16
+ throw new ZoomError("validation_error", "speech model directory must be an absolute bounded path");
17
+ for (const [value, max, label] of [
18
+ [options.maxBytes, 4 * 1024 ** 3, "media bytes"],
19
+ [options.maxDurationMs, 24 * 3600_000, "media duration"],
20
+ [options.maxSegments, 100000, "segment count"],
21
+ [options.maxTextBytes, 64 * 1024 ** 2, "transcript text bytes"],
22
+ ])
23
+ if (value !== undefined && (!Number.isSafeInteger(value) || value < 1 || value > max))
24
+ throw new ZoomError("validation_error", `invalid ${label} budget`);
25
+ for (const value of [options.apply, options.dryRun])
26
+ if (value !== undefined && typeof value !== "boolean")
27
+ throw new ZoomError("validation_error", "transcription apply and dry-run options must be booleans");
28
+ return options;
29
+ };
30
+ export const compactLocalTranscriptionReceipt = (receipt) => {
31
+ const append = receipt.append;
32
+ if (!receipt.applied || !append || !Number.isSafeInteger(append.meeting.meeting.id) || append.meeting.meeting.id < 1)
33
+ throw new ZoomError("outcome_unknown", "transcription did not return a usable committed acknowledgement");
34
+ return {
35
+ applied: true,
36
+ accountId: receipt.accountId,
37
+ externalId: receipt.externalId,
38
+ meetingId: append.meeting.meeting.id,
39
+ created: append.created,
40
+ insertedTranscripts: append.insertedTranscripts,
41
+ replayedTranscripts: append.replayedTranscripts,
42
+ supersededTranscripts: append.supersededTranscripts,
43
+ segments: receipt.segments,
44
+ mediaSha256: receipt.media.contentHash,
45
+ engine: receipt.media.recognition.engine,
46
+ model: receipt.media.recognition.model,
47
+ modelVersion: receipt.media.recognition.version ?? null,
48
+ timing: receipt.media.recognition.timing ?? "recognition-segments",
49
+ };
50
+ };
51
+ const loadSpeech = async () => {
52
+ const speech = await import("@wirecat/cli-messaging/speech");
53
+ return { describe: speech.localSpeechRecognitionModel, open: speech.openLocalSpeechRecognizer };
54
+ };
55
+ export const createWavTranscriptionSource = (file, options) => {
56
+ const selected = { ...options, ...(options.env ? { env: { ...options.env } } : {}) };
57
+ let plan;
58
+ let recognition;
59
+ let speech;
60
+ return {
61
+ async describe(context) {
62
+ checkCancelled(context.signal);
63
+ speech = await (selected.speech ?? loadSpeech)();
64
+ recognition = Object.freeze({ ...speech.describe(selected.model) });
65
+ plan = await preflightWavAudio(file, context);
66
+ return Object.freeze({
67
+ ...plan.media,
68
+ recognition: Object.freeze({
69
+ engine: recognition.engine,
70
+ model: recognition.model,
71
+ version: recognition.version,
72
+ timing: "fixed-windows",
73
+ }),
74
+ });
75
+ },
76
+ async *segments(media, context) {
77
+ if (!plan ||
78
+ !recognition ||
79
+ !speech ||
80
+ media.contentHash !== plan.media.contentHash ||
81
+ media.id !== plan.media.id ||
82
+ media.size !== plan.media.size ||
83
+ media.durationMs !== plan.media.durationMs ||
84
+ media.recognition.engine !== recognition.engine ||
85
+ media.recognition.model !== recognition.model ||
86
+ media.recognition.version !== recognition.version)
87
+ throw new ZoomError("validation_error", "transcription media descriptor does not match its prepared audio and model");
88
+ const audio = await openWavAudio(plan, context);
89
+ let model;
90
+ try {
91
+ checkCancelled(context.signal);
92
+ model = await speech.open(recognition.model, {
93
+ directory: selected.modelsDirectory,
94
+ env: selected.env,
95
+ signal: context.signal,
96
+ });
97
+ if (model.engine !== recognition.engine ||
98
+ model.model !== recognition.model ||
99
+ model.version !== recognition.version)
100
+ throw new ZoomError("validation_error", "installed speech recognizer changed after the media preview");
101
+ for await (const window of audio.windows()) {
102
+ checkCancelled(context.signal);
103
+ const text = await model.recognize(window.samples, { signal: context.signal });
104
+ checkCancelled(context.signal);
105
+ yield { startMs: window.startMs, endMs: window.endMs, text };
106
+ }
107
+ }
108
+ finally {
109
+ try {
110
+ await model?.close();
111
+ }
112
+ finally {
113
+ await audio.close();
114
+ }
115
+ }
116
+ },
117
+ };
118
+ };
119
+ export const createLocalTranscriptionCapabilities = (store, input = {}) => {
120
+ const accountId = store.accountId;
121
+ if (!Number.isSafeInteger(accountId) || accountId < 1)
122
+ throw new ZoomError("validation_error", "local transcription requires a selected existing account");
123
+ const options = { ...input, ...(input.env ? { env: { ...input.env } } : {}) };
124
+ const resolveMeeting = store.resolveMeeting.bind(store);
125
+ const appendTranscriptsWithReceipt = store.appendTranscriptsWithReceipt.bind(store);
126
+ return {
127
+ async transcribe(reference, file, raw) {
128
+ const request = validateLocalTranscriptionOptions(raw);
129
+ checkCancelled(request.signal);
130
+ const resolved = await resolveMeeting(reference, request.signal);
131
+ const found = resolved && {
132
+ accountId: resolved.accountId,
133
+ meetingId: resolved.meetingId,
134
+ externalId: resolved.externalId,
135
+ };
136
+ if (!found ||
137
+ found.accountId !== accountId ||
138
+ !Number.isSafeInteger(found.meetingId) ||
139
+ found.meetingId < 1 ||
140
+ typeof found.externalId !== "string" ||
141
+ !found.externalId.trim())
142
+ throw new ZoomError("not_found", "meeting was not found in the selected account");
143
+ const target = Object.freeze({ accountId, externalId: found.externalId, now: options.now?.() ?? Date.now() });
144
+ const source = createWavTranscriptionSource(file, {
145
+ model: request.model,
146
+ modelsDirectory: request.modelsDirectory,
147
+ env: options.env,
148
+ speech: options.speech,
149
+ });
150
+ const { transcribeMeeting } = await import("@wirecat/cli-meetings");
151
+ return transcribeMeeting(source, {
152
+ appendTranscriptsWithReceipt(value) {
153
+ if (value.accountId !== accountId || value.externalId !== target.externalId)
154
+ throw new ZoomError("validation_error", "transcription append must retain its selected target");
155
+ return appendTranscriptsWithReceipt(value);
156
+ },
157
+ }, target, request);
158
+ },
159
+ };
160
+ };
161
+ //# sourceMappingURL=local-transcription.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-transcription.js","sourceRoot":"","sources":["../src/local-transcription.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Command } from "commander";
2
+ import { type MeetingIntegrationCapabilities } from "./meeting-integration.js";
3
+ export declare const addMeetingIntegrationCommands: (program: Command, deps: {
4
+ integration: () => Promise<MeetingIntegrationCapabilities>;
5
+ signal: () => AbortSignal | undefined;
6
+ output: (value: unknown) => void;
7
+ receipt: (value: unknown) => Promise<void>;
8
+ }) => void;
9
+ //# sourceMappingURL=meeting-integration-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meeting-integration-commands.d.ts","sourceRoot":"","sources":["../src/meeting-integration-commands.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,OAAO,EAEL,KAAK,8BAA8B,EAEpC,MAAM,0BAA0B,CAAA;AAEjC,eAAO,MAAM,6BAA6B,YAC/B,OAAO,QACV;IACJ,WAAW,EAAE,MAAM,OAAO,CAAC,8BAA8B,CAAC,CAAA;IAC1D,MAAM,EAAE,MAAM,WAAW,GAAG,SAAS,CAAA;IACrC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAChC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3C,SAgGF,CAAA"}
@@ -0,0 +1,64 @@
1
+ import { annotate } from "@wirecat/cli-core/commands";
2
+ import { validateMeetingContextChange } from "@wirecat/cli-meetings";
3
+ import { ZoomError } from "./errors.js";
4
+ import { bytes } from "./execution.js";
5
+ import { integrationReference, } from "./meeting-integration.js";
6
+ export const addMeetingIntegrationCommands = (program, deps) => {
7
+ const meetings = program.commands.find((command) => command.name() === "meetings");
8
+ if (!meetings)
9
+ throw new ZoomError("configuration_error", "meeting command group is unavailable");
10
+ const label = (command, example, mutates = false) => annotate(command, {
11
+ origin: "handwritten",
12
+ mutates,
13
+ ...(mutates ? { local: true } : {}),
14
+ examples: [example],
15
+ });
16
+ const guards = (command) => command.option("--yes", "apply this local change once").option("--dry-run", "preview even when --yes is present");
17
+ const apply = async (reference, input, options) => {
18
+ const target = integrationReference(reference);
19
+ const change = validateMeetingContextChange(input);
20
+ if (change.action !== "event.link" && change.action !== "person.link")
21
+ throw new ZoomError("validation_error", "meeting linking supports only explicit event or person changes");
22
+ const result = await (await deps.integration()).change(target.reference, change, {
23
+ apply: options.yes,
24
+ dryRun: options.dryRun,
25
+ signal: deps.signal(),
26
+ });
27
+ if (result.applied)
28
+ await deps.receipt(result);
29
+ else
30
+ deps.output(result);
31
+ };
32
+ const nullableId = (value) => (value === "none" ? "none" : bytes(value));
33
+ label(guards(meetings
34
+ .command("link-event")
35
+ .description("preview or apply an owner-selected event link")
36
+ .argument("<reference>")
37
+ .requiredOption("--event-id <id>", "stored event id, or none to unlink", nullableId)
38
+ .option("--expected-event-id <id>", "compare current event id, or none", nullableId)).action(async (reference, options) => apply(reference, {
39
+ action: "event.link",
40
+ eventId: options.eventId === "none" ? null : options.eventId,
41
+ ...(options.expectedEventId === undefined
42
+ ? {}
43
+ : { expectedEventId: options.expectedEventId === "none" ? null : options.expectedEventId }),
44
+ }, options)), "zm meetings link-event meeting:1/1 --event-id 1 --yes --json", true);
45
+ label(guards(meetings
46
+ .command("link-person")
47
+ .description("preview or apply an explicit participant identity link to a stored person")
48
+ .argument("<reference>")
49
+ .requiredOption("--participant-id <id>", "participant id from this meeting", bytes)
50
+ .requiredOption("--person <uid>", "explicit stored person UID")
51
+ .option("--target-accounts <ids>", "explicit additional account ids authorized for target-person lookup")
52
+ .option("--expected-person <uid>", "compare current person UID, or none")).action(async (reference, options) => apply(reference, {
53
+ action: "person.link",
54
+ participantId: options.participantId,
55
+ personUid: options.person,
56
+ ...(options.targetAccounts === undefined
57
+ ? {}
58
+ : { targetAccountIds: options.targetAccounts.split(",").map((item) => bytes(item.trim())) }),
59
+ ...(options.expectedPerson === undefined
60
+ ? {}
61
+ : { expectedPersonUid: options.expectedPerson === "none" ? null : options.expectedPerson }),
62
+ }, options)), "zm meetings link-person meeting:1/1 --participant-id 1 --person 1 --yes --json", true);
63
+ };
64
+ //# sourceMappingURL=meeting-integration-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meeting-integration-commands.js","sourceRoot":"","sources":["../src/meeting-integration-commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { MeetingContextChange, MeetingContextReceipt, MeetingMutationOptions } from "@wirecat/cli-meetings";
2
+ export type MeetingLinkChange = Extract<MeetingContextChange, {
3
+ action: "event.link" | "person.link";
4
+ }>;
5
+ export interface MeetingIntegrationCapabilities {
6
+ change(reference: string, change: MeetingLinkChange, options?: MeetingMutationOptions): Promise<MeetingContextReceipt<unknown>>;
7
+ }
8
+ export declare const integrationReference: (reference: string) => {
9
+ parsed: import("@wirecat/cli-messaging").MeetingReference;
10
+ reference: string;
11
+ };
12
+ //# sourceMappingURL=meeting-integration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meeting-integration.d.ts","sourceRoot":"","sources":["../src/meeting-integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAIhH,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,oBAAoB,EAAE;IAAE,MAAM,EAAE,YAAY,GAAG,aAAa,CAAA;CAAE,CAAC,CAAA;AACvG,MAAM,WAAW,8BAA8B;IAC7C,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,iBAAiB,EACzB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAA;CAC3C;AAED,eAAO,MAAM,oBAAoB,cAAe,MAAM;;;CAKrD,CAAA"}
@@ -0,0 +1,9 @@
1
+ import { canonicalMeetingReference, parseMeetingReference } from "@wirecat/cli-messaging";
2
+ import { ZoomError } from "./errors.js";
3
+ export const integrationReference = (reference) => {
4
+ const parsed = parseMeetingReference(reference);
5
+ if (parsed.transcriptId !== undefined)
6
+ throw new ZoomError("validation_error", "this operation requires a root meeting reference");
7
+ return { parsed, reference: canonicalMeetingReference(reference) };
8
+ };
9
+ //# sourceMappingURL=meeting-integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meeting-integration.js","sourceRoot":"","sources":["../src/meeting-integration.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AACzF,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAWvC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,SAAiB,EAAE,EAAE;IACxD,MAAM,MAAM,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAA;IAC/C,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS;QACnC,MAAM,IAAI,SAAS,CAAC,kBAAkB,EAAE,kDAAkD,CAAC,CAAA;IAC7F,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,yBAAyB,CAAC,SAAS,CAAC,EAAE,CAAA;AACpE,CAAC,CAAA"}
@@ -0,0 +1,33 @@
1
+ import type { MeetingSearchOptions, MeetingSearchPage } from "@wirecat/cli-meetings";
2
+ import type { Command } from "commander";
3
+ export type MeetingHitSearchOptions = Omit<MeetingSearchOptions, "accountId">;
4
+ export type MeetingHitSearch = (query: string, options: MeetingHitSearchOptions) => Promise<MeetingSearchPage>;
5
+ export type MeetingSearchIndex = (options: {
6
+ limit?: number;
7
+ maxReadBytes?: number;
8
+ apply?: boolean;
9
+ dryRun?: boolean;
10
+ signal?: AbortSignal;
11
+ }) => Promise<{
12
+ applied: boolean;
13
+ accountId: number;
14
+ indexed?: number;
15
+ remaining?: number;
16
+ request: {
17
+ limit: number;
18
+ maxReadBytes: number;
19
+ };
20
+ }>;
21
+ export declare const validateMeetingHitSearch: (query: string, options?: MeetingHitSearchOptions) => void;
22
+ export declare const addMeetingHitSearchCommand: (program: Command, deps: {
23
+ search: () => Promise<MeetingHitSearch>;
24
+ signal: () => AbortSignal | undefined;
25
+ output: (value: unknown) => void;
26
+ }) => void;
27
+ export declare const addMeetingSearchIndexCommand: (program: Command, deps: {
28
+ index: () => Promise<MeetingSearchIndex>;
29
+ signal: () => AbortSignal | undefined;
30
+ output: (value: unknown) => void;
31
+ receipt: (value: unknown) => Promise<void>;
32
+ }) => void;
33
+ //# sourceMappingURL=meeting-search-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meeting-search-commands.d.ts","sourceRoot":"","sources":["../src/meeting-search-commands.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACpF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAIxC,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAAA;AAC7E,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAA;AAC9G,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE;IACzC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,KAAK,OAAO,CAAC;IACZ,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAA;CACjD,CAAC,CAAA;AAEF,eAAO,MAAM,wBAAwB,UAAW,MAAM,YAAW,uBAAuB,SAkBvF,CAAA;AAcD,eAAO,MAAM,0BAA0B,YAC5B,OAAO,QACV;IACJ,MAAM,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACvC,MAAM,EAAE,MAAM,WAAW,GAAG,SAAS,CAAA;IACrC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;CACjC,SA8BF,CAAA;AAED,eAAO,MAAM,4BAA4B,YAC9B,OAAO,QACV;IACJ,KAAK,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACxC,MAAM,EAAE,MAAM,WAAW,GAAG,SAAS,CAAA;IACrC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAChC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3C,SA0BF,CAAA"}
@@ -0,0 +1,85 @@
1
+ import { annotate } from "@wirecat/cli-core/commands";
2
+ import { ZoomError } from "./errors.js";
3
+ import { bytes } from "./execution.js";
4
+ export const validateMeetingHitSearch = (query, options = {}) => {
5
+ const integer = (value, low, high) => Number.isSafeInteger(value) && value >= low && value <= high;
6
+ if (typeof query !== "string" ||
7
+ !query.trim() ||
8
+ query.includes("\0") ||
9
+ new TextEncoder().encode(query).byteLength > 65536 ||
10
+ !integer(options.limit ?? 100, 1, 1000) ||
11
+ !integer(options.maxReadBytes ?? 4194304, 1, 67108864) ||
12
+ (options.meetingId !== undefined && !integer(options.meetingId, 1, Number.MAX_SAFE_INTEGER)) ||
13
+ (options.since !== undefined && !integer(options.since, -8640000000000000, 8640000000000000)) ||
14
+ (options.until !== undefined && !integer(options.until, -8640000000000000, 8640000000000000)) ||
15
+ (options.since !== undefined && options.until !== undefined && options.since > options.until) ||
16
+ (options.after !== undefined &&
17
+ (typeof options.after !== "string" || !/^[A-Za-z0-9_-]{1,1000}$/.test(options.after))))
18
+ throw new ZoomError("validation_error", "invalid bounded meeting search query, cursor or limits");
19
+ };
20
+ const timestamp = (value) => {
21
+ const parsed = Date.parse(value);
22
+ const date = value.slice(0, 10);
23
+ const day = Date.parse(`${date}T00:00:00Z`);
24
+ if (!/^\d{4}-\d{2}-\d{2}(?:T.+(?:Z|[+-]\d{2}:\d{2}))?$/.test(value) ||
25
+ !Number.isFinite(parsed) ||
26
+ !Number.isFinite(day) ||
27
+ new Date(day).toISOString().slice(0, 10) !== date)
28
+ throw new ZoomError("validation_error", "meeting search dates require a real ISO date or timestamp with offset");
29
+ return parsed;
30
+ };
31
+ export const addMeetingHitSearchCommand = (program, deps) => {
32
+ const meetings = program.commands.find((command) => command.name() === "meetings");
33
+ if (!meetings)
34
+ throw new ZoomError("configuration_error", "meeting command group is unavailable");
35
+ annotate(meetings
36
+ .command("search-page")
37
+ .description("bounded keyword search with configured stemming and hit continuation")
38
+ .argument("<query>")
39
+ .option("--meeting-id <id>", "restrict to a meeting in the selected account", bytes)
40
+ .option("--since <date>", "meeting start at or after an ISO date or timestamp", timestamp)
41
+ .option("--until <date>", "meeting start at or before an ISO date or timestamp", timestamp)
42
+ .option("--limit <count>", "hit limit from 1 through 1000 (default 100)", bytes)
43
+ .option("--after <cursor>", "opaque nextCursor from the same query and selected account")
44
+ .option("--max-read-bytes <bytes>", "raw SQL read budget from 1 through 67108864 (default 4194304)", bytes)
45
+ .action(async (query, options) => {
46
+ validateMeetingHitSearch(query, options);
47
+ const request = {
48
+ meetingId: options.meetingId,
49
+ since: options.since,
50
+ until: options.until,
51
+ limit: options.limit,
52
+ after: options.after,
53
+ maxReadBytes: options.maxReadBytes,
54
+ signal: deps.signal(),
55
+ };
56
+ deps.output(await (await deps.search())(query, request));
57
+ }), { origin: "handwritten", mutates: false, examples: ['zm meetings search-page "Alice Example" --limit 20 --json'] });
58
+ };
59
+ export const addMeetingSearchIndexCommand = (program, deps) => {
60
+ const meetings = program.commands.find((command) => command.name() === "meetings");
61
+ if (!meetings)
62
+ throw new ZoomError("configuration_error", "meeting command group is unavailable");
63
+ annotate(meetings
64
+ .command("search-index")
65
+ .description("preview or apply one bounded batch of queued meeting search indexing")
66
+ .option("--limit <count>", "queued record limit from 1 through 1000 (default 100)", bytes)
67
+ .option("--max-read-bytes <bytes>", "raw SQL read budget from 1 through 67108864 (default 4194304)", bytes)
68
+ .option("--yes", "apply this indexing batch once")
69
+ .option("--dry-run", "preview even when --yes is present")
70
+ .action(async (options) => {
71
+ validateMeetingHitSearch("index", options);
72
+ const result = await (await deps.index())({
73
+ limit: options.limit,
74
+ maxReadBytes: options.maxReadBytes,
75
+ apply: options.yes,
76
+ dryRun: options.dryRun,
77
+ signal: deps.signal(),
78
+ });
79
+ if (result.applied)
80
+ await deps.receipt(result);
81
+ else
82
+ deps.output(result);
83
+ }), { origin: "handwritten", mutates: true, local: true, examples: ["zm meetings search-index --yes --json"] });
84
+ };
85
+ //# sourceMappingURL=meeting-search-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meeting-search-commands.js","sourceRoot":"","sources":["../src/meeting-search-commands.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { type FileHandle } from "node:fs/promises";
2
2
  /** Check the opened object before reading: Windows has no O_NOFOLLOW support. */
3
3
  export declare const openOrdinaryFile: (path: string) => Promise<FileHandle>;
4
+ export declare const syncDirectory: (path: string) => Promise<void>;
4
5
  //# sourceMappingURL=ordinary-file.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ordinary-file.d.ts","sourceRoot":"","sources":["../src/ordinary-file.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAe,MAAM,kBAAkB,CAAA;AAM/D,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,SAAgB,MAAM,KAAG,OAAO,CAAC,UAAU,CA0CvE,CAAA"}
1
+ {"version":3,"file":"ordinary-file.d.ts","sourceRoot":"","sources":["../src/ordinary-file.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAe,MAAM,kBAAkB,CAAA;AAM/D,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,SAAgB,MAAM,KAAG,OAAO,CAAC,UAAU,CA0CvE,CAAA;AAED,eAAO,MAAM,aAAa,SAAgB,MAAM,KAAG,OAAO,CAAC,IAAI,CAU9D,CAAA"}