@wirecat/zoom-cli 0.1.1 → 0.2.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 (85) hide show
  1. package/README.md +136 -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 +25 -0
  11. package/dist/archive-commands.d.ts.map +1 -0
  12. package/dist/archive-commands.js +157 -0
  13. package/dist/archive-commands.js.map +1 -0
  14. package/dist/bin/zm.js +53 -3
  15. package/dist/bin/zm.js.map +1 -1
  16. package/dist/commands.d.ts +12 -0
  17. package/dist/commands.d.ts.map +1 -0
  18. package/dist/commands.js +96 -0
  19. package/dist/commands.js.map +1 -0
  20. package/dist/errors.d.ts +4 -3
  21. package/dist/errors.d.ts.map +1 -1
  22. package/dist/errors.js +11 -4
  23. package/dist/errors.js.map +1 -1
  24. package/dist/execution.d.ts +16 -0
  25. package/dist/execution.d.ts.map +1 -0
  26. package/dist/execution.js +49 -0
  27. package/dist/execution.js.map +1 -0
  28. package/dist/index.d.ts +5 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +5 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/login.d.ts +1 -0
  33. package/dist/login.d.ts.map +1 -1
  34. package/dist/login.js +13 -1
  35. package/dist/login.js.map +1 -1
  36. package/dist/mcp-server.d.ts +16 -0
  37. package/dist/mcp-server.d.ts.map +1 -0
  38. package/dist/mcp-server.js +172 -0
  39. package/dist/mcp-server.js.map +1 -0
  40. package/dist/output-file.d.ts +4 -0
  41. package/dist/output-file.d.ts.map +1 -0
  42. package/dist/output-file.js +55 -0
  43. package/dist/output-file.js.map +1 -0
  44. package/dist/program.d.ts +21 -0
  45. package/dist/program.d.ts.map +1 -1
  46. package/dist/program.js +317 -44
  47. package/dist/program.js.map +1 -1
  48. package/dist/recording-archive.d.ts +62 -0
  49. package/dist/recording-archive.d.ts.map +1 -0
  50. package/dist/recording-archive.js +519 -0
  51. package/dist/recording-archive.js.map +1 -0
  52. package/dist/recording-sync.d.ts +15 -0
  53. package/dist/recording-sync.d.ts.map +1 -0
  54. package/dist/recording-sync.js +49 -0
  55. package/dist/recording-sync.js.map +1 -0
  56. package/dist/recordings.d.ts +47 -0
  57. package/dist/recordings.d.ts.map +1 -0
  58. package/dist/recordings.js +124 -0
  59. package/dist/recordings.js.map +1 -0
  60. package/dist/remote-http.d.ts +23 -0
  61. package/dist/remote-http.d.ts.map +1 -0
  62. package/dist/remote-http.js +113 -0
  63. package/dist/remote-http.js.map +1 -0
  64. package/dist/remote-meetings.d.ts +58 -0
  65. package/dist/remote-meetings.d.ts.map +1 -0
  66. package/dist/remote-meetings.js +151 -0
  67. package/dist/remote-meetings.js.map +1 -0
  68. package/dist/store-connection.d.ts +9 -0
  69. package/dist/store-connection.d.ts.map +1 -0
  70. package/dist/store-connection.js +39 -0
  71. package/dist/store-connection.js.map +1 -0
  72. package/dist/streaming.d.ts +6 -0
  73. package/dist/streaming.d.ts.map +1 -0
  74. package/dist/streaming.js +86 -0
  75. package/dist/streaming.js.map +1 -0
  76. package/dist/tokens.d.ts +6 -4
  77. package/dist/tokens.d.ts.map +1 -1
  78. package/dist/tokens.js +48 -18
  79. package/dist/tokens.js.map +1 -1
  80. package/dist/watch-commands.d.ts +11 -0
  81. package/dist/watch-commands.d.ts.map +1 -0
  82. package/dist/watch-commands.js +30 -0
  83. package/dist/watch-commands.js.map +1 -0
  84. package/package.json +21 -12
  85. package/skills/zoom-cli/SKILL.md +69 -0
@@ -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,11 @@
1
+ import { type RunReport, type WatchSleep } from "@wirecat/cli-meetings";
2
+ import type { Command } from "commander";
3
+ export interface WatchCommandDeps {
4
+ signal: () => AbortSignal;
5
+ ingest: (folder: string, signal: AbortSignal) => Promise<RunReport>;
6
+ receipt: (report: RunReport) => Promise<void>;
7
+ sleep?: WatchSleep;
8
+ outputIsTTY?: boolean;
9
+ }
10
+ export declare const addWatchCommand: (program: Command, deps: WatchCommandDeps) => void;
11
+ //# 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,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAIxC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,WAAW,CAAA;IACzB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,SAAS,CAAC,CAAA;IACnE,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;AACD,eAAO,MAAM,eAAe,YAAa,OAAO,QAAQ,gBAAgB,KAAG,IAuB1E,CAAA"}
@@ -0,0 +1,30 @@
1
+ import { annotate } from "@wirecat/cli-core/commands";
2
+ import { watchMeetingIngestion } from "@wirecat/cli-meetings";
3
+ import { ZoomError } from "./errors.js";
4
+ import { duration } from "./execution.js";
5
+ export const addWatchCommand = (program, deps) => {
6
+ const command = program
7
+ .command("watch")
8
+ .description("foreground serial folder rescans; completed receipts stream after each store close")
9
+ .argument("<folder>", "downloaded VTT/TXT folder")
10
+ .option("--interval <duration>", "delay after each completed receipt (1s through 24h)", duration, 10000)
11
+ .action(async (folder, options) => {
12
+ if (!program.opts().jsonl && !deps.outputIsTTY)
13
+ throw new ZoomError("validation_error", "headless watch requires --jsonl");
14
+ if (program.opts().json)
15
+ throw new ZoomError("validation_error", "watch streams receipts; use --jsonl");
16
+ for await (const report of watchMeetingIngestion((signal) => deps.ingest(folder, signal), {
17
+ signal: deps.signal(),
18
+ intervalMs: options.interval,
19
+ sleep: deps.sleep,
20
+ }))
21
+ await deps.receipt(report);
22
+ });
23
+ annotate(command, {
24
+ origin: "handwritten",
25
+ mutates: true,
26
+ local: true,
27
+ examples: ["zm watch ./downloads --interval 10s --jsonl"],
28
+ });
29
+ };
30
+ //# sourceMappingURL=watch-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-commands.js","sourceRoot":"","sources":["../src/watch-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AACrD,OAAO,EAAmC,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAE9F,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AASzC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAgB,EAAE,IAAsB,EAAQ,EAAE;IAChF,MAAM,OAAO,GAAG,OAAO;SACpB,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,oFAAoF,CAAC;SACjG,QAAQ,CAAC,UAAU,EAAE,2BAA2B,CAAC;SACjD,MAAM,CAAC,uBAAuB,EAAE,qDAAqD,EAAE,QAAQ,EAAE,KAAK,CAAC;SACvG,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,OAA6B,EAAE,EAAE;QAC9D,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,WAAW;YAC5C,MAAM,IAAI,SAAS,CAAC,kBAAkB,EAAE,iCAAiC,CAAC,CAAA;QAC5E,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI;YAAE,MAAM,IAAI,SAAS,CAAC,kBAAkB,EAAE,qCAAqC,CAAC,CAAA;QACvG,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI,qBAAqB,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE;YACxF,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE;YACrB,UAAU,EAAE,OAAO,CAAC,QAAQ;YAC5B,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;YACA,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAC9B,CAAC,CAAC,CAAA;IACJ,QAAQ,CAAC,OAAO,EAAE;QAChB,MAAM,EAAE,aAAa;QACrB,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,IAAI;QACX,QAAQ,EAAE,CAAC,6CAA6C,CAAC;KAC1D,CAAC,CAAA;AACJ,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@wirecat/zoom-cli",
3
- "version": "0.1.1",
4
- "description": "Zoom meetings, transcripts and summaries through provider-neutral meeting tools",
3
+ "version": "0.2.0",
4
+ "description": "Zoom cloud recording archives, persistent transcripts and meeting tools",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
7
  "engines": {
8
- "node": ">=22.12.0"
8
+ "node": "^22.16.0 || >=24"
9
9
  },
10
10
  "packageManager": "pnpm@11.20.0",
11
11
  "repository": {
@@ -17,6 +17,7 @@
17
17
  },
18
18
  "files": [
19
19
  "dist",
20
+ "skills",
20
21
  "README.md",
21
22
  "LICENSE"
22
23
  ],
@@ -35,21 +36,29 @@
35
36
  "test:coverage": "vitest run --coverage",
36
37
  "smoke:bun": "bun run scripts/smoke.ts",
37
38
  "prepublishOnly": "pnpm build",
38
- "docs:check": "node node_modules/@wirecat/cli-core/dist/dev/bin.js docs-check --rules scripts/docs-rules.ts && cspell --no-progress --no-summary README.md && node node_modules/rumdl/bin/rumdl check --config node_modules/@wirecat/cli-core/config/rumdl.toml README.md CHANGELOG.md CLAUDE.md docs/dev/*.md"
39
+ "docs:check": "node node_modules/@wirecat/cli-core/dist/dev/bin.js docs-check --rules scripts/docs-rules.ts && cspell --no-progress --no-summary README.md && node node_modules/rumdl/bin/rumdl check --config config/wirecat/rumdl.toml README.md CHANGELOG.md CLAUDE.md docs/dev/*.md",
40
+ "standards:check": "node config/wirecat/check.mjs",
41
+ "docs:lint": "markdownlint-cli2",
42
+ "docs:spell": "cspell lint --config cspell.json --no-progress README.md",
43
+ "prepare": "lefthook install || true"
39
44
  },
40
45
  "dependencies": {
41
- "@wirecat/cli-core": "0.18.1",
42
- "@wirecat/cli-meetings": "0.2.3",
43
- "commander": "15.0.0"
46
+ "@modelcontextprotocol/sdk": "1.32.1",
47
+ "@wirecat/cli-core": "0.19.3",
48
+ "@wirecat/cli-meetings": "0.2.4",
49
+ "commander": "15.0.0",
50
+ "@wirecat/cli-messaging": "0.218.0"
44
51
  },
45
52
  "devDependencies": {
46
- "@biomejs/biome": "^2.5.15",
47
- "@cspell/dict-en-gb": "^5.0.34",
48
- "@cspell/dict-ru_ru": "^2.3.2",
53
+ "@biomejs/biome": "2.5.15",
54
+ "@cspell/dict-en-gb": "5.0.34",
55
+ "@cspell/dict-es-es": "3.0.9",
56
+ "@cspell/dict-ru_ru": "2.3.3",
49
57
  "@types/node": "^22.20.5",
50
58
  "@vitest/coverage-v8": "^5.0.3",
51
- "cspell": "^10.3.6",
52
- "lefthook": "^2.1.16",
59
+ "cspell": "10.3.6",
60
+ "lefthook": "2.1.16",
61
+ "markdownlint-cli2": "0.23.3",
53
62
  "rumdl": "^0.2.78",
54
63
  "typescript": "^7.0.2",
55
64
  "vitest": "^5.0.3"
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: zoom-cli
3
+ description: Archive Zoom cloud recordings, read stored meeting transcripts and summaries, or manage a Zoom meeting through zm. Use for Zoom CLI workflows, not joining calls or operating the desktop video client.
4
+ metadata:
5
+ version: "0.2.0"
6
+ ---
7
+
8
+ # Zoom CLI
9
+
10
+ Use `zm commands <resource> --json` and `zm <resource> --help` for the installed version's capabilities.
11
+ Use JSON for finite reads and JSONL for foreground watches or batch synchronization. Keep diagnostics
12
+ on stderr; use `--fields` to limit returned content. `zm doctor --json` checks local setup without login.
13
+
14
+ ## Recording archives
15
+
16
+ Use `recordings sync --from <date> --to <date> --destination <directory> --jsonl` to archive history
17
+ across months. It emits serial occurrence receipts and accepts up to ten calendar years.
18
+ Use `recordings list` to find cloud recording occurrences, then `recordings show <id-or-uuid>` to
19
+ inspect assets. Download with `recordings download <id-or-uuid> --destination <directory>`.
20
+ Prefer occurrence UUIDs for recurring meetings. Download access depends on Zoom scopes and the
21
+ signed-in account; attending a meeting does not imply access to its recording API.
22
+
23
+ Re-run against the same destination to skip verified manifest entries. Use `recordings archive verify`
24
+ for local checksums; it works with `--offline`. The receipt distinguishes downloaded, skipped and
25
+ unavailable assets. A failed transfer can leave earlier completed files; retry starts the incomplete
26
+ file again. Existing files are never overwritten. Do not infer HTTP byte-range resume.
27
+
28
+ `recordings archive locks` inspects writer locks. `recover` previews stale lock removal; `--yes`
29
+ removes recognized dead-process locks on this machine. It does not repair incomplete manifests or
30
+ adopt untracked files. Keep active and foreign locks intact.
31
+
32
+ ## Stored meeting content
33
+
34
+ Stored `meetings` ids are local database ids, different from remote Zoom ids. Use `meetings show`,
35
+ `transcript`, `summary` and `search` for local reads. `transcript --history` includes retained versions.
36
+ Export Markdown or VTT with `meetings export <id> --format markdown|vtt`; file output requires an
37
+ explicit `--output` path and never overwrites an existing file. VTT export requires an unambiguous
38
+ current transcript or an explicit transcript id.
39
+
40
+ Store commands use the shared SQLite database; `MESSAGING_STORE` selects an explicit path. Select a
41
+ local profile before import or pull. Reads require existing profile data; they do not register it. `pull --lookback-days` revisits late
42
+ transcripts. File imports preserve the API pull cursor. Serialize ingestion for the same account.
43
+ Local profile labels group stored data and do not select a different OAuth account.
44
+
45
+ `zm watch <folder> --jsonl` rescans legacy transcript files in the foreground; each cycle closes its
46
+ connection before emitting a receipt. Stop with Ctrl-C. Fully completed late receipts have at most
47
+ one second to flush; cancellation never starts another cycle. Hashed cloud archive VTT assets do
48
+ not use legacy filenames and have no direct database-import command yet.
49
+
50
+ `zm serve --mcp` provides seven read-only stored meeting tools. Discovery opens no database; reads
51
+ use the selected account. MCP uses its own framing, so omit JSON/JSONL/field-selection flags.
52
+
53
+ ## Remote meeting changes
54
+
55
+ `remote-meetings` uses numeric Zoom meeting ids. Create, update and cancel preview by default;
56
+ `--yes` applies a change once, and `--dry-run` always previews. Follow the user's authorization for
57
+ actual mutations. Exit code 14 means a dispatched operation has an uncertain outcome: inspect remote
58
+ state before retrying. Do not automatically retry creation or cancellation.
59
+
60
+ ## Authentication and execution
61
+
62
+ Missing-scope errors name the required scope; add it to the public OAuth app and log in again.
63
+ Browser login requires interactive input; `--interactive` permits piped/JSON login only when an input
64
+ terminal is present. `--no-input` cannot approve browser consent. Never extract or print keyring tokens.
65
+ Cached `session status` does not contact Zoom; `--check` explicitly verifies remotely.
66
+
67
+ Use `--timeout <milliseconds>` for a positive whole-command deadline and cancellation for foreground
68
+ jobs. `--offline` refuses network access. Recording videos stream to disk; ordinary result output is
69
+ bounded by `--max-output-bytes`, separate from the download's per-file `--max-bytes` limit.