@wirecat/zoom-cli 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/README.md +165 -9
  2. package/dist/agent-skill.d.ts +4 -0
  3. package/dist/agent-skill.d.ts.map +1 -0
  4. package/dist/agent-skill.js +16 -0
  5. package/dist/agent-skill.js.map +1 -0
  6. package/dist/api.d.ts +3 -2
  7. package/dist/api.d.ts.map +1 -1
  8. package/dist/api.js +10 -41
  9. package/dist/api.js.map +1 -1
  10. package/dist/archive-commands.d.ts +32 -0
  11. package/dist/archive-commands.d.ts.map +1 -0
  12. package/dist/archive-commands.js +182 -0
  13. package/dist/archive-commands.js.map +1 -0
  14. package/dist/archive-transcripts.d.ts +33 -0
  15. package/dist/archive-transcripts.d.ts.map +1 -0
  16. package/dist/archive-transcripts.js +131 -0
  17. package/dist/archive-transcripts.js.map +1 -0
  18. package/dist/bin/zm.js +53 -3
  19. package/dist/bin/zm.js.map +1 -1
  20. package/dist/commands.d.ts +12 -0
  21. package/dist/commands.d.ts.map +1 -0
  22. package/dist/commands.js +96 -0
  23. package/dist/commands.js.map +1 -0
  24. package/dist/errors.d.ts +4 -3
  25. package/dist/errors.d.ts.map +1 -1
  26. package/dist/errors.js +11 -4
  27. package/dist/errors.js.map +1 -1
  28. package/dist/execution.d.ts +16 -0
  29. package/dist/execution.d.ts.map +1 -0
  30. package/dist/execution.js +49 -0
  31. package/dist/execution.js.map +1 -0
  32. package/dist/index.d.ts +6 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +6 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/login.d.ts +1 -0
  37. package/dist/login.d.ts.map +1 -1
  38. package/dist/login.js +13 -1
  39. package/dist/login.js.map +1 -1
  40. package/dist/mcp-server.d.ts +16 -0
  41. package/dist/mcp-server.d.ts.map +1 -0
  42. package/dist/mcp-server.js +172 -0
  43. package/dist/mcp-server.js.map +1 -0
  44. package/dist/output-file.d.ts +4 -0
  45. package/dist/output-file.d.ts.map +1 -0
  46. package/dist/output-file.js +55 -0
  47. package/dist/output-file.js.map +1 -0
  48. package/dist/program.d.ts +22 -0
  49. package/dist/program.d.ts.map +1 -1
  50. package/dist/program.js +443 -44
  51. package/dist/program.js.map +1 -1
  52. package/dist/recording-archive.d.ts +62 -0
  53. package/dist/recording-archive.d.ts.map +1 -0
  54. package/dist/recording-archive.js +519 -0
  55. package/dist/recording-archive.js.map +1 -0
  56. package/dist/recording-sync.d.ts +15 -0
  57. package/dist/recording-sync.d.ts.map +1 -0
  58. package/dist/recording-sync.js +49 -0
  59. package/dist/recording-sync.js.map +1 -0
  60. package/dist/recordings.d.ts +47 -0
  61. package/dist/recordings.d.ts.map +1 -0
  62. package/dist/recordings.js +124 -0
  63. package/dist/recordings.js.map +1 -0
  64. package/dist/remote-http.d.ts +23 -0
  65. package/dist/remote-http.d.ts.map +1 -0
  66. package/dist/remote-http.js +113 -0
  67. package/dist/remote-http.js.map +1 -0
  68. package/dist/remote-meetings.d.ts +58 -0
  69. package/dist/remote-meetings.d.ts.map +1 -0
  70. package/dist/remote-meetings.js +151 -0
  71. package/dist/remote-meetings.js.map +1 -0
  72. package/dist/store-connection.d.ts +9 -0
  73. package/dist/store-connection.d.ts.map +1 -0
  74. package/dist/store-connection.js +39 -0
  75. package/dist/store-connection.js.map +1 -0
  76. package/dist/streaming.d.ts +6 -0
  77. package/dist/streaming.d.ts.map +1 -0
  78. package/dist/streaming.js +86 -0
  79. package/dist/streaming.js.map +1 -0
  80. package/dist/tokens.d.ts +6 -4
  81. package/dist/tokens.d.ts.map +1 -1
  82. package/dist/tokens.js +48 -18
  83. package/dist/tokens.js.map +1 -1
  84. package/dist/watch-commands.d.ts +25 -0
  85. package/dist/watch-commands.d.ts.map +1 -0
  86. package/dist/watch-commands.js +52 -0
  87. package/dist/watch-commands.js.map +1 -0
  88. package/package.json +22 -12
  89. package/skills/zoom-cli/SKILL.md +85 -0
@@ -0,0 +1,151 @@
1
+ import { object, string, ZoomError } from "./errors.js";
2
+ import { required } from "./recordings.js";
3
+ import { operationSignal, ZoomRemote } from "./remote-http.js";
4
+ const idPath = (id) => {
5
+ if (!/^[1-9]\d*$/.test(id))
6
+ throw new ZoomError("validation_error", "remote meeting id must be a positive numeric id");
7
+ return `/meetings/${id}`;
8
+ };
9
+ const normalized = (value) => {
10
+ const row = object(value);
11
+ const id = typeof row.id === "number" && Number.isSafeInteger(row.id) ? String(row.id) : required(row.id);
12
+ idPath(id);
13
+ return {
14
+ id,
15
+ uuid: string(row.uuid),
16
+ title: string(row.topic),
17
+ type: typeof row.type === "number" ? row.type : null,
18
+ startedAt: string(row.start_time),
19
+ durationMinutes: typeof row.duration === "number" && Number.isFinite(row.duration) && row.duration >= 0 ? row.duration : null,
20
+ timezone: string(row.timezone),
21
+ agenda: string(row.agenda),
22
+ joinUrl: string(row.join_url),
23
+ };
24
+ };
25
+ const changeBody = (change, create) => {
26
+ if (!change ||
27
+ Object.keys(change).some((key) => !["topic", "startTime", "durationMinutes", "timezone", "agenda", "type"].includes(key)))
28
+ throw new ZoomError("validation_error", "unsupported meeting change field");
29
+ const body = {};
30
+ if (change.topic !== undefined) {
31
+ if (!string(change.topic))
32
+ throw new ZoomError("validation_error", "meeting topic must be nonempty");
33
+ body.topic = change.topic;
34
+ }
35
+ if (create && !string(change.topic))
36
+ throw new ZoomError("validation_error", "meeting topic is required");
37
+ if (change.startTime !== undefined) {
38
+ if (typeof change.startTime !== "string" ||
39
+ !/T.+(?:Z|[+-]\d{2}:\d{2})$/i.test(change.startTime) ||
40
+ !Number.isFinite(Date.parse(change.startTime)))
41
+ throw new ZoomError("validation_error", "meeting start must be an ISO timestamp with a timezone");
42
+ const date = change.startTime.slice(0, 10);
43
+ const dateInstant = Date.parse(`${date}T00:00:00Z`);
44
+ if (!Number.isFinite(dateInstant) || new Date(dateInstant).toISOString().slice(0, 10) !== date)
45
+ throw new ZoomError("validation_error", "meeting start contains an invalid calendar date");
46
+ body.start_time = new Date(change.startTime).toISOString();
47
+ }
48
+ if (change.durationMinutes !== undefined) {
49
+ if (!Number.isSafeInteger(change.durationMinutes) || change.durationMinutes <= 0 || change.durationMinutes > 1440)
50
+ throw new ZoomError("validation_error", "meeting duration must be an integer from 1 to 1440 minutes");
51
+ body.duration = change.durationMinutes;
52
+ }
53
+ if (change.timezone !== undefined) {
54
+ try {
55
+ new Intl.DateTimeFormat("en", { timeZone: change.timezone }).format();
56
+ }
57
+ catch {
58
+ throw new ZoomError("validation_error", "meeting timezone must be a valid IANA timezone");
59
+ }
60
+ body.timezone = change.timezone;
61
+ }
62
+ if (change.agenda !== undefined) {
63
+ if (typeof change.agenda !== "string")
64
+ throw new ZoomError("validation_error", "meeting agenda must be text");
65
+ body.agenda = change.agenda;
66
+ }
67
+ if (change.type !== undefined && change.type !== 1 && change.type !== 2)
68
+ throw new ZoomError("validation_error", "only instant or scheduled meeting types are supported");
69
+ if (create) {
70
+ body.type = change.type ?? 2;
71
+ if (body.type === 2 && body.start_time === undefined)
72
+ throw new ZoomError("validation_error", "scheduled meeting start is required");
73
+ }
74
+ else {
75
+ if (change.type !== undefined)
76
+ body.type = change.type;
77
+ if (Object.keys(body).length === 0)
78
+ throw new ZoomError("validation_error", "at least one meeting change is required");
79
+ }
80
+ return body;
81
+ };
82
+ export class ZoomRemoteMeetings {
83
+ remote;
84
+ constructor(tokens, fetcher, options = {}) {
85
+ this.remote = new ZoomRemote(tokens, fetcher, options);
86
+ }
87
+ async list(options = {}) {
88
+ const signal = operationSignal(options.signal);
89
+ const query = new URLSearchParams({ type: "upcoming", page_size: "100" });
90
+ const seen = new Set();
91
+ const result = new Map();
92
+ for (;;) {
93
+ const body = await this.remote.request(`/users/me/meetings?${query}`, "meeting:read:list_meetings", { signal });
94
+ if (!Array.isArray(body.meetings))
95
+ throw new ZoomError("invalid_response", "Zoom returned an invalid meeting list");
96
+ for (const row of body.meetings) {
97
+ const item = normalized(row);
98
+ result.set(item.id, item);
99
+ }
100
+ const next = string(body.next_page_token);
101
+ if (!next)
102
+ return [...result.values()];
103
+ if (seen.has(next))
104
+ throw new ZoomError("invalid_response", "Zoom repeated a pagination token");
105
+ seen.add(next);
106
+ query.set("next_page_token", next);
107
+ }
108
+ }
109
+ async show(id, options = {}) {
110
+ return normalized(await this.remote.request(idPath(id), "meeting:read:meeting", options));
111
+ }
112
+ async invitation(id, options = {}) {
113
+ const body = await this.remote.request(`${idPath(id)}/invitation`, "meeting:read:invitation", options);
114
+ return { id, invitation: required(body.invitation) };
115
+ }
116
+ async mutate(action, request, scope, options) {
117
+ const result = { action, applied: false, request };
118
+ if (!options.apply || options.dryRun)
119
+ return result;
120
+ const init = {
121
+ method: request.method,
122
+ ...(request.body ? { body: request.body } : {}),
123
+ ...(options.signal ? { signal: options.signal } : {}),
124
+ };
125
+ const body = await this.remote.request(request.path, scope, init);
126
+ result.applied = true;
127
+ if (action === "create") {
128
+ try {
129
+ result.meeting = normalized(body);
130
+ }
131
+ catch {
132
+ throw new ZoomError("outcome_unknown", "Zoom mutation returned incomplete meeting details; verify remote state before retrying");
133
+ }
134
+ }
135
+ return result;
136
+ }
137
+ create(change, options = {}) {
138
+ return this.mutate("create", { method: "POST", path: "/users/me/meetings", body: changeBody(change, true) }, "meeting:write:meeting", options);
139
+ }
140
+ update(id, change, options = {}) {
141
+ return this.mutate("update", { method: "PATCH", path: idPath(id), body: changeBody(change, false) }, "meeting:update:meeting", options);
142
+ }
143
+ cancel(id, options = {}) {
144
+ const path = idPath(id);
145
+ if (options.occurrenceId !== undefined && !string(options.occurrenceId))
146
+ throw new ZoomError("validation_error", "occurrence id must be nonempty");
147
+ const query = options.occurrenceId ? `?${new URLSearchParams({ occurrence_id: options.occurrenceId })}` : "";
148
+ return this.mutate("cancel", { method: "DELETE", path: `${path}${query}` }, "meeting:delete:meeting", options);
149
+ }
150
+ }
151
+ //# sourceMappingURL=remote-meetings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-meetings.js","sourceRoot":"","sources":["../src/remote-meetings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { MessageStore, StoreOptions } from "@wirecat/cli-messaging/store";
2
+ import type { StoreConnection, StoreConnectRequest } from "./program.js";
3
+ type SharedMeetingStore = Pick<MessageStore, "meetings" | "saveAccount" | "storedAccount" | "close">;
4
+ export interface StoreConnectionOptions extends StoreOptions {
5
+ openStore?: (options: StoreOptions) => Promise<SharedMeetingStore>;
6
+ }
7
+ export declare const createStoreConnector: (options?: StoreConnectionOptions) => (request: StoreConnectRequest) => Promise<StoreConnection>;
8
+ export {};
9
+ //# sourceMappingURL=store-connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-connection.d.ts","sourceRoot":"","sources":["../src/store-connection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAG9E,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAExE,KAAK,kBAAkB,GAAG,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,aAAa,GAAG,eAAe,GAAG,OAAO,CAAC,CAAA;AACpG,MAAM,WAAW,sBAAuB,SAAQ,YAAY;IAC1D,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAA;CACnE;AAED,eAAO,MAAM,oBAAoB,aACrB,sBAAsB,eAChB,mBAAmB,KAAG,OAAO,CAAC,eAAe,CAwC5D,CAAA"}
@@ -0,0 +1,39 @@
1
+ import { CliError } from "@wirecat/cli-core";
2
+ import { profileAccountKey } from "./config.js";
3
+ import { ZoomError } from "./errors.js";
4
+ export const createStoreConnector = (options = {}) => async (request) => {
5
+ if (typeof request?.profile !== "string" ||
6
+ !/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(request.profile) ||
7
+ request.externalId !== profileAccountKey(request.profile) ||
8
+ (request.intent !== "read" && request.intent !== "ingestion"))
9
+ throw new ZoomError("validation_error", "expected a selected Zoom profile and read or ingestion intent");
10
+ let store;
11
+ try {
12
+ const open = options.openStore ?? (await import("@wirecat/cli-messaging/store")).openStore;
13
+ store = await open({ path: options.path, env: options.env, now: options.now });
14
+ const key = { provider: "zoom", account: request.externalId };
15
+ const accountId = request.intent === "ingestion"
16
+ ? await store.saveAccount(key, { name: request.profile })
17
+ : (await store.storedAccount(key)).id;
18
+ if (!Number.isSafeInteger(accountId) || accountId < 1)
19
+ throw new ZoomError("configuration_error", "the selected meeting account is unavailable");
20
+ const connected = store;
21
+ return { store: connected.meetings, accountId, close: () => connected.close() };
22
+ }
23
+ catch (error) {
24
+ if (store) {
25
+ try {
26
+ await store.close();
27
+ }
28
+ catch {
29
+ /* Preserve the setup failure. */
30
+ }
31
+ }
32
+ if (error instanceof ZoomError)
33
+ throw error;
34
+ if (error instanceof CliError && error.code === "not_found")
35
+ throw new ZoomError("configuration_error", "no stored meetings for the selected profile; import transcripts or pull first");
36
+ throw new ZoomError("configuration_error", "could not connect to the shared meeting store; check MESSAGING_STORE and the installed store version");
37
+ }
38
+ };
39
+ //# sourceMappingURL=store-connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-connection.js","sourceRoot":"","sources":["../src/store-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAQvC,MAAM,CAAC,MAAM,oBAAoB,GAC/B,CAAC,OAAO,GAA2B,EAAE,EAAE,EAAE,CACzC,KAAK,EAAE,OAA4B,EAA4B,EAAE;IAC/D,IACE,OAAO,OAAO,EAAE,OAAO,KAAK,QAAQ;QACpC,CAAC,mCAAmC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QAC1D,OAAO,CAAC,UAAU,KAAK,iBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC;QACzD,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,WAAW,CAAC;QAE7D,MAAM,IAAI,SAAS,CAAC,kBAAkB,EAAE,+DAA+D,CAAC,CAAA;IAC1G,IAAI,KAAqC,CAAA;IACzC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,IAAI,CAAC,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC,CAAC,SAAS,CAAA;QAC1F,KAAK,GAAG,MAAM,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;QAC9E,MAAM,GAAG,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE,CAAA;QAC7D,MAAM,SAAS,GACb,OAAO,CAAC,MAAM,KAAK,WAAW;YAC5B,CAAC,CAAC,MAAM,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;YACzD,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;QACzC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC;YACnD,MAAM,IAAI,SAAS,CAAC,qBAAqB,EAAE,6CAA6C,CAAC,CAAA;QAC3F,MAAM,SAAS,GAAG,KAAK,CAAA;QACvB,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,CAAA;IACjF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC;gBACH,MAAM,KAAK,CAAC,KAAK,EAAE,CAAA;YACrB,CAAC;YAAC,MAAM,CAAC;gBACP,iCAAiC;YACnC,CAAC;QACH,CAAC;QACD,IAAI,KAAK,YAAY,SAAS;YAAE,MAAM,KAAK,CAAA;QAC3C,IAAI,KAAK,YAAY,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;YACzD,MAAM,IAAI,SAAS,CACjB,qBAAqB,EACrB,+EAA+E,CAChF,CAAA;QACH,MAAM,IAAI,SAAS,CACjB,qBAAqB,EACrB,sGAAsG,CACvG,CAAA;IACH,CAAC;AACH,CAAC,CAAA"}
@@ -0,0 +1,6 @@
1
+ import type { Writable } from "node:stream";
2
+ /** Await kernel-facing stdout backpressure before advancing another ingestion/download cycle. */
3
+ export declare const writeStream: (stream: Writable, text: string, signal: AbortSignal) => Promise<void>;
4
+ /** Bound each complete receipt, without retaining the foreground stream. */
5
+ export declare const emitReceipt: (text: string, maxOutputBytes: number | undefined, write: (text: string) => Promise<void>) => Promise<void>;
6
+ //# sourceMappingURL=streaming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../src/streaming.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAI3C,iGAAiG;AACjG,eAAO,MAAM,WAAW,WAAY,QAAQ,QAAQ,MAAM,UAAU,WAAW,KAAG,OAAO,CAAC,IAAI,CA4D7F,CAAA;AAED,4EAA4E;AAC5E,eAAO,MAAM,WAAW,SAChB,MAAM,kBACI,MAAM,GAAG,SAAS,SAC3B,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,KACrC,OAAO,CAAC,IAAI,CAQd,CAAA"}
@@ -0,0 +1,86 @@
1
+ import { createOutputBuffer } from "@wirecat/cli-core";
2
+ import { checkCancelled, ZoomError } from "./errors.js";
3
+ /** Await kernel-facing stdout backpressure before advancing another ingestion/download cycle. */
4
+ export const writeStream = (stream, text, signal) => {
5
+ checkCancelled(signal);
6
+ return new Promise((resolve, reject) => {
7
+ let settled = false;
8
+ let returned = false;
9
+ let callbackDone = false;
10
+ let needsDrain = false;
11
+ let drained = false;
12
+ let callbackFailed = false;
13
+ let errorObserved = false;
14
+ const outputError = () => new ZoomError("configuration_error", "could not write command output");
15
+ const removeGuard = () => stream.removeListener("error", failed);
16
+ const done = (error) => {
17
+ if (settled)
18
+ return;
19
+ settled = true;
20
+ stream.removeListener("drain", onDrain);
21
+ signal.removeEventListener("abort", aborted);
22
+ if (callbackDone && (!callbackFailed || errorObserved))
23
+ removeGuard();
24
+ if (error)
25
+ reject(error);
26
+ else
27
+ resolve();
28
+ };
29
+ const finish = () => {
30
+ if (returned && callbackDone && (!needsDrain || drained))
31
+ done();
32
+ };
33
+ const onDrain = () => {
34
+ drained = true;
35
+ finish();
36
+ };
37
+ const failed = () => {
38
+ errorObserved = true;
39
+ done(outputError());
40
+ if (callbackDone)
41
+ removeGuard();
42
+ };
43
+ const aborted = () => {
44
+ try {
45
+ checkCancelled(signal);
46
+ }
47
+ catch (error) {
48
+ done(error);
49
+ }
50
+ };
51
+ signal.addEventListener("abort", aborted, { once: true });
52
+ // A submitted write can fail after cancellation. Keep this guard until its callback/error settles.
53
+ stream.on("error", failed);
54
+ stream.on("drain", onDrain);
55
+ try {
56
+ needsDrain = !stream.write(text, (error) => {
57
+ callbackDone = true;
58
+ callbackFailed = Boolean(error);
59
+ if (error)
60
+ done(outputError());
61
+ else
62
+ finish();
63
+ if (settled && (!callbackFailed || errorObserved))
64
+ removeGuard();
65
+ });
66
+ returned = true;
67
+ finish();
68
+ }
69
+ catch {
70
+ callbackDone = true;
71
+ errorObserved = true;
72
+ done(outputError());
73
+ }
74
+ });
75
+ };
76
+ /** Bound each complete receipt, without retaining the foreground stream. */
77
+ export const emitReceipt = async (text, maxOutputBytes, write) => {
78
+ const output = createOutputBuffer({ maxOutputBytes });
79
+ output.data(text);
80
+ let serialized = "";
81
+ output.flush((chunk) => {
82
+ serialized += chunk;
83
+ });
84
+ await write(serialized);
85
+ };
86
+ //# sourceMappingURL=streaming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.js","sourceRoot":"","sources":["../src/streaming.ts"],"names":[],"mappings":"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"}
package/dist/tokens.d.ts CHANGED
@@ -11,14 +11,16 @@ export interface TokenOptions {
11
11
  service: string;
12
12
  fetch: typeof fetch;
13
13
  now?: () => number;
14
+ signal?: AbortSignal;
14
15
  }
15
16
  export declare class TokenManager {
16
17
  readonly options: TokenOptions;
17
- private refreshing;
18
+ private refreshState;
18
19
  constructor(options: TokenOptions);
19
- load(): Tokens | null;
20
- save(tokens: Tokens): void;
21
- exchange(params: Record<string, string>, previous?: Tokens): Promise<Tokens>;
20
+ withSignal(signal?: AbortSignal, fetcher?: typeof fetch): TokenManager;
21
+ load(clientId?: string): Tokens | null;
22
+ save(tokens: Tokens, clientId?: string): void;
23
+ exchange(params: Record<string, string>, previous?: Tokens, clientId?: string): Promise<Tokens>;
22
24
  tokens(): Promise<Tokens>;
23
25
  }
24
26
  //# sourceMappingURL=tokens.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGrD,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB;AACD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,YAAY,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,OAAO,KAAK,CAAA;IACnB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AACD,qBAAa,YAAY;IAEX,QAAQ,CAAC,OAAO,EAAE,YAAY;IAD1C,OAAO,CAAC,UAAU,CAA6B;IAC/C,YAAqB,OAAO,EAAE,YAAY,EAAI;IAC9C,IAAI,IAAI,MAAM,GAAG,IAAI,CA8BpB;IACD,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAMzB;IACK,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4CjF;IACK,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAW9B;CACF"}
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGrD,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB;AACD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,YAAY,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,OAAO,KAAK,CAAA;IACnB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AACD,qBAAa,YAAY;IAEX,QAAQ,CAAC,OAAO,EAAE,YAAY;IAD1C,OAAO,CAAC,YAAY,CAAqC;IACzD,YAAqB,OAAO,EAAE,YAAY,EAAI;IAC9C,UAAU,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,OAAO,GAAE,OAAO,KAA0B,GAAG,YAAY,CAgBzF;IACD,IAAI,CAAC,QAAQ,SAAwB,GAAG,MAAM,GAAG,IAAI,CA8BpD;IACD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAwB,GAAG,IAAI,CAM3D;IACK,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,SAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuDnH;IACK,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAoB9B;CACF"}
package/dist/tokens.js CHANGED
@@ -1,14 +1,31 @@
1
- import { object, ZoomError } from "./errors.js";
1
+ import { checkCancelled, object, ZoomError } from "./errors.js";
2
2
  export class TokenManager {
3
3
  options;
4
- refreshing;
4
+ refreshState = new Map();
5
5
  constructor(options) {
6
6
  this.options = options;
7
7
  }
8
- load() {
8
+ withSignal(signal, fetcher = this.options.fetch) {
9
+ const parent = this.options;
10
+ let clientId;
11
+ const scoped = new TokenManager({
12
+ get clientId() {
13
+ clientId ??= parent.clientId;
14
+ return clientId;
15
+ },
16
+ keyring: parent.keyring,
17
+ service: parent.service,
18
+ fetch: fetcher,
19
+ now: parent.now,
20
+ signal: signal && parent.signal ? AbortSignal.any([signal, parent.signal]) : (signal ?? parent.signal),
21
+ });
22
+ scoped.refreshState = this.refreshState;
23
+ return scoped;
24
+ }
25
+ load(clientId = this.options.clientId) {
9
26
  let saved;
10
27
  try {
11
- saved = this.options.keyring.get(this.options.service, this.options.clientId);
28
+ saved = this.options.keyring.get(this.options.service, clientId);
12
29
  }
13
30
  catch {
14
31
  throw new ZoomError("configuration_error", "system keyring is unavailable");
@@ -37,26 +54,31 @@ export class TokenManager {
37
54
  throw new ZoomError("authentication_error", "saved login is invalid; run zm login again");
38
55
  }
39
56
  }
40
- save(tokens) {
57
+ save(tokens, clientId = this.options.clientId) {
41
58
  try {
42
- this.options.keyring.set(this.options.service, this.options.clientId, JSON.stringify(tokens));
59
+ this.options.keyring.set(this.options.service, clientId, JSON.stringify(tokens));
43
60
  }
44
61
  catch {
45
62
  throw new ZoomError("configuration_error", "could not save login to the system keyring");
46
63
  }
47
64
  }
48
- async exchange(params, previous) {
65
+ async exchange(params, previous, clientId = this.options.clientId) {
66
+ checkCancelled(this.options.signal);
67
+ const signal = this.options.signal
68
+ ? AbortSignal.any([this.options.signal, AbortSignal.timeout(30000)])
69
+ : AbortSignal.timeout(30000);
49
70
  let response;
50
71
  try {
51
72
  response = await this.options.fetch("https://zoom.us/oauth/token", {
52
73
  method: "POST",
53
74
  headers: { "content-type": "application/x-www-form-urlencoded" },
54
- body: new URLSearchParams({ ...params, client_id: this.options.clientId }),
55
- signal: AbortSignal.timeout(30000),
75
+ body: new URLSearchParams({ ...params, client_id: clientId }),
76
+ signal,
77
+ redirect: "error",
56
78
  });
57
79
  }
58
80
  catch {
59
- throw new ZoomError("provider_error", "could not reach Zoom token endpoint; retry the command");
81
+ throw new ZoomError("outcome_unknown", "Zoom token exchange did not finish; run zm login again before retrying");
60
82
  }
61
83
  if (!response.ok)
62
84
  throw new ZoomError("authentication_error", `Zoom token request failed (HTTP ${response.status}); run zm login again`);
@@ -65,7 +87,7 @@ export class TokenManager {
65
87
  body = object(await response.json());
66
88
  }
67
89
  catch {
68
- throw new ZoomError("invalid_response", "Zoom returned an invalid token response");
90
+ throw new ZoomError("outcome_unknown", "Zoom returned an invalid token response; run zm login again before retrying");
69
91
  }
70
92
  const refreshToken = typeof body.refresh_token === "string" ? body.refresh_token : previous?.refreshToken;
71
93
  if (typeof body.access_token !== "string" ||
@@ -77,26 +99,34 @@ export class TokenManager {
77
99
  !Number.isFinite((this.options.now?.() ?? Date.now()) + body.expires_in * 1000) ||
78
100
  (body.scope !== undefined && typeof body.scope !== "string") ||
79
101
  (body.refresh_token !== undefined && typeof body.refresh_token !== "string"))
80
- throw new ZoomError("invalid_response", "Zoom returned an invalid token response");
102
+ throw new ZoomError("outcome_unknown", "Zoom returned an invalid token response; run zm login again before retrying");
81
103
  const tokens = {
82
104
  accessToken: body.access_token,
83
105
  refreshToken,
84
106
  expiresAt: (this.options.now?.() ?? Date.now()) + body.expires_in * 1000,
85
107
  scopes: typeof body.scope === "string" ? body.scope.split(/\s+/).filter(Boolean) : (previous?.scopes ?? []),
86
108
  };
87
- this.save(tokens);
109
+ this.save(tokens, clientId);
88
110
  return tokens;
89
111
  }
90
112
  async tokens() {
91
- const saved = this.load();
113
+ checkCancelled(this.options.signal);
114
+ const clientId = this.options.clientId;
115
+ const saved = this.load(clientId);
92
116
  if (!saved)
93
117
  throw new ZoomError("authentication_error", "run zm login first");
94
118
  if (saved.expiresAt > (this.options.now?.() ?? Date.now()) + 30000)
95
119
  return saved;
96
- this.refreshing ??= this.exchange({ grant_type: "refresh_token", refresh_token: saved.refreshToken }, saved).finally(() => {
97
- this.refreshing = undefined;
98
- });
99
- return this.refreshing;
120
+ let refreshing = this.refreshState.get(clientId);
121
+ if (!refreshing) {
122
+ refreshing = this.exchange({ grant_type: "refresh_token", refresh_token: saved.refreshToken }, saved, clientId).finally(() => {
123
+ this.refreshState.delete(clientId);
124
+ });
125
+ this.refreshState.set(clientId, refreshing);
126
+ }
127
+ const refreshed = await refreshing;
128
+ checkCancelled(this.options.signal);
129
+ return refreshed;
100
130
  }
101
131
  }
102
132
  //# sourceMappingURL=tokens.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type RunReport, type WatchSleep } from "@wirecat/cli-meetings";
2
+ import { type Command } from "commander";
3
+ export interface WatchFlags {
4
+ source?: "api" | "files";
5
+ since?: string;
6
+ lookbackDays?: number;
7
+ interval: number;
8
+ }
9
+ export interface WatchPlan {
10
+ source: "api" | "files";
11
+ folder?: string;
12
+ since?: string;
13
+ lookbackDays: number;
14
+ intervalMs: number;
15
+ }
16
+ export interface WatchCommandDeps {
17
+ signal: () => AbortSignal;
18
+ prepare: (folder: string | undefined, flags: WatchFlags) => WatchPlan;
19
+ ingest: (plan: WatchPlan, signal: AbortSignal) => Promise<RunReport>;
20
+ receipt: (report: RunReport) => Promise<void>;
21
+ sleep?: WatchSleep;
22
+ outputIsTTY?: boolean;
23
+ }
24
+ export declare const addWatchCommand: (program: Command, deps: WatchCommandDeps) => void;
25
+ //# sourceMappingURL=watch-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-commands.d.ts","sourceRoot":"","sources":["../src/watch-commands.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAyB,MAAM,uBAAuB,CAAA;AAC9F,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,WAAW,CAAA;AAIhD,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,KAAK,GAAG,OAAO,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;CACjB;AACD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,KAAK,GAAG,OAAO,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;CACnB;AACD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,WAAW,CAAA;IACzB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,UAAU,KAAK,SAAS,CAAA;IACrE,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,SAAS,CAAC,CAAA;IACpE,OAAO,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7C,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAkBD,eAAO,MAAM,eAAe,YAAa,OAAO,QAAQ,gBAAgB,KAAG,IA+B1E,CAAA"}
@@ -0,0 +1,52 @@
1
+ import { annotate } from "@wirecat/cli-core/commands";
2
+ import { watchMeetingIngestion } from "@wirecat/cli-meetings";
3
+ import { Option } from "commander";
4
+ import { ZoomError } from "./errors.js";
5
+ import { duration } from "./execution.js";
6
+ const days = (value) => {
7
+ if (!/^\d+$/.test(value) || Number(value) > 31)
8
+ throw new ZoomError("validation_error", "lookback days must be an integer from 0 through 31");
9
+ return Number(value);
10
+ };
11
+ const since = (value) => {
12
+ const day = value.slice(0, 10);
13
+ const dayTime = Date.parse(`${day}T00:00:00Z`);
14
+ if (!/^\d{4}-\d{2}-\d{2}T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(value) ||
15
+ !Number.isFinite(Date.parse(value)) ||
16
+ !Number.isFinite(dayTime) ||
17
+ new Date(dayTime).toISOString().slice(0, 10) !== day)
18
+ throw new ZoomError("validation_error", "since must be a real ISO timestamp with timezone");
19
+ return value;
20
+ };
21
+ export const addWatchCommand = (program, deps) => {
22
+ const command = program
23
+ .command("watch")
24
+ .description("foreground serial API pulls or folder rescans, with closed-store receipts")
25
+ .argument("[folder]", "downloaded VTT/TXT folder; defaults source to files")
26
+ .addOption(new Option("--source <source>", "api or files; otherwise uses configured source").choices(["api", "files"]))
27
+ .option("--since <timestamp>", "initial API lower bound until the first successful cursor write", since)
28
+ .option("--lookback-days <days>", "API cursor overlap for late transcripts (0 through 31)", days)
29
+ .option("--interval <duration>", "delay after each completed receipt (1s through 24h)", duration, 10000)
30
+ .action(async (folder, options) => {
31
+ if (!program.opts().jsonl && !deps.outputIsTTY)
32
+ throw new ZoomError("validation_error", "headless watch requires --jsonl");
33
+ if (program.opts().json)
34
+ throw new ZoomError("validation_error", "watch streams receipts; use --jsonl");
35
+ if (options.interval < 1000 || options.interval > 86400000)
36
+ throw new ZoomError("validation_error", "watch interval must be from 1s through 24h");
37
+ const plan = deps.prepare(folder, options);
38
+ for await (const report of watchMeetingIngestion((signal) => deps.ingest(plan, signal), {
39
+ signal: deps.signal(),
40
+ intervalMs: plan.intervalMs,
41
+ sleep: deps.sleep,
42
+ }))
43
+ await deps.receipt(report);
44
+ });
45
+ annotate(command, {
46
+ origin: "handwritten",
47
+ mutates: true,
48
+ local: true,
49
+ examples: ["zm watch ./downloads --interval 10s --jsonl", "zm watch --source api --lookback-days 2 --jsonl"],
50
+ });
51
+ };
52
+ //# sourceMappingURL=watch-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-commands.js","sourceRoot":"","sources":["../src/watch-commands.ts"],"names":[],"mappings":"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"}