@wirecat/zoom-cli 0.1.0 → 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.
- package/README.md +156 -11
- package/dist/agent-skill.d.ts +4 -0
- package/dist/agent-skill.d.ts.map +1 -0
- package/dist/agent-skill.js +16 -0
- package/dist/agent-skill.js.map +1 -0
- package/dist/api.d.ts +3 -2
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +10 -41
- package/dist/api.js.map +1 -1
- package/dist/archive-commands.d.ts +25 -0
- package/dist/archive-commands.d.ts.map +1 -0
- package/dist/archive-commands.js +157 -0
- package/dist/archive-commands.js.map +1 -0
- package/dist/bin/zm.js +53 -3
- package/dist/bin/zm.js.map +1 -1
- package/dist/commands.d.ts +12 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +96 -0
- package/dist/commands.js.map +1 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -2
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +4 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +11 -4
- package/dist/errors.js.map +1 -1
- package/dist/execution.d.ts +16 -0
- package/dist/execution.d.ts.map +1 -0
- package/dist/execution.js +49 -0
- package/dist/execution.js.map +1 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/login.d.ts +1 -0
- package/dist/login.d.ts.map +1 -1
- package/dist/login.js +13 -1
- package/dist/login.js.map +1 -1
- package/dist/mcp-server.d.ts +16 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +172 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/output-file.d.ts +4 -0
- package/dist/output-file.d.ts.map +1 -0
- package/dist/output-file.js +55 -0
- package/dist/output-file.js.map +1 -0
- package/dist/program.d.ts +32 -0
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +403 -45
- package/dist/program.js.map +1 -1
- package/dist/recording-archive.d.ts +62 -0
- package/dist/recording-archive.d.ts.map +1 -0
- package/dist/recording-archive.js +519 -0
- package/dist/recording-archive.js.map +1 -0
- package/dist/recording-sync.d.ts +15 -0
- package/dist/recording-sync.d.ts.map +1 -0
- package/dist/recording-sync.js +49 -0
- package/dist/recording-sync.js.map +1 -0
- package/dist/recordings.d.ts +47 -0
- package/dist/recordings.d.ts.map +1 -0
- package/dist/recordings.js +124 -0
- package/dist/recordings.js.map +1 -0
- package/dist/remote-http.d.ts +23 -0
- package/dist/remote-http.d.ts.map +1 -0
- package/dist/remote-http.js +113 -0
- package/dist/remote-http.js.map +1 -0
- package/dist/remote-meetings.d.ts +58 -0
- package/dist/remote-meetings.d.ts.map +1 -0
- package/dist/remote-meetings.js +151 -0
- package/dist/remote-meetings.js.map +1 -0
- package/dist/store-connection.d.ts +9 -0
- package/dist/store-connection.d.ts.map +1 -0
- package/dist/store-connection.js +39 -0
- package/dist/store-connection.js.map +1 -0
- package/dist/streaming.d.ts +6 -0
- package/dist/streaming.d.ts.map +1 -0
- package/dist/streaming.js +86 -0
- package/dist/streaming.js.map +1 -0
- package/dist/tokens.d.ts +6 -4
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js +48 -18
- package/dist/tokens.js.map +1 -1
- package/dist/watch-commands.d.ts +11 -0
- package/dist/watch-commands.d.ts.map +1 -0
- package/dist/watch-commands.js +30 -0
- package/dist/watch-commands.js.map +1 -0
- package/package.json +21 -12
- 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
|
|
18
|
+
private refreshState;
|
|
18
19
|
constructor(options: TokenOptions);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
package/dist/tokens.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
-
|
|
4
|
+
refreshState = new Map();
|
|
5
5
|
constructor(options) {
|
|
6
6
|
this.options = options;
|
|
7
7
|
}
|
|
8
|
-
|
|
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,
|
|
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,
|
|
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:
|
|
55
|
-
signal
|
|
75
|
+
body: new URLSearchParams({ ...params, client_id: clientId }),
|
|
76
|
+
signal,
|
|
77
|
+
redirect: "error",
|
|
56
78
|
});
|
|
57
79
|
}
|
|
58
80
|
catch {
|
|
59
|
-
throw new ZoomError("
|
|
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("
|
|
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("
|
|
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
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
package/dist/tokens.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;
|
|
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.
|
|
4
|
-
"description": "Zoom
|
|
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": "
|
|
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
|
|
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
|
-
"@
|
|
42
|
-
"@wirecat/cli-
|
|
43
|
-
"
|
|
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": "
|
|
47
|
-
"@cspell/dict-en-gb": "
|
|
48
|
-
"@cspell/dict-
|
|
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": "
|
|
52
|
-
"lefthook": "
|
|
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.
|