@wirecat/zoom-cli 0.50.1 → 0.52.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 +2 -0
- package/dist/answer-entities.d.ts +14 -0
- package/dist/answer-entities.d.ts.map +1 -1
- package/dist/answer-entities.js +12 -0
- package/dist/answer-entities.js.map +1 -1
- package/dist/contacts-commands.d.ts +11 -0
- package/dist/contacts-commands.d.ts.map +1 -0
- package/dist/contacts-commands.js +49 -0
- package/dist/contacts-commands.js.map +1 -0
- package/dist/contacts.d.ts +29 -0
- package/dist/contacts.d.ts.map +1 -0
- package/dist/contacts.js +70 -0
- package/dist/contacts.js.map +1 -0
- package/dist/contract-overrides.js +1 -1
- package/dist/contract-overrides.js.map +1 -1
- package/dist/program-bindings.d.ts.map +1 -1
- package/dist/program-bindings.js +16 -0
- package/dist/program-bindings.js.map +1 -1
- package/dist/program.d.ts +6 -0
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js.map +1 -1
- package/dist/setup-commands.d.ts +1 -1
- package/dist/setup-commands.d.ts.map +1 -1
- package/dist/setup-commands.js +19 -4
- package/dist/setup-commands.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/zoom-api/schemas.d.ts +9 -0
- package/dist/zoom-api/schemas.d.ts.map +1 -0
- package/dist/zoom-api/schemas.js +50 -0
- package/dist/zoom-api/schemas.js.map +1 -0
- package/dist/zoom-api/types.d.ts +52 -0
- package/dist/zoom-api/types.d.ts.map +1 -0
- package/dist/zoom-api/types.js +5 -0
- package/dist/zoom-api/types.js.map +1 -0
- package/dist/zoom-mcp.d.ts +14 -0
- package/dist/zoom-mcp.d.ts.map +1 -0
- package/dist/zoom-mcp.js +120 -0
- package/dist/zoom-mcp.js.map +1 -0
- package/dist/zoom-search-commands.d.ts +11 -0
- package/dist/zoom-search-commands.d.ts.map +1 -0
- package/dist/zoom-search-commands.js +57 -0
- package/dist/zoom-search-commands.js.map +1 -0
- package/dist/zoom-search.d.ts +48 -0
- package/dist/zoom-search.d.ts.map +1 -0
- package/dist/zoom-search.js +99 -0
- package/dist/zoom-search.js.map +1 -0
- package/package.json +7 -4
- package/skills/zoom-cli/SKILL.md +5 -1
package/dist/setup-commands.js
CHANGED
|
@@ -2,7 +2,7 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { dirname } from "node:path";
|
|
3
3
|
import { CliError } from "@wirecat/cli-base";
|
|
4
4
|
import { annotate } from "@wirecat/cli-base/commands";
|
|
5
|
-
import { commandWords, grantsAuthority, itemOf, LOCAL_READ, LOCAL_WRITE, logsInOrOut, NO_EFFECTS, privateFiles, REMOTE_WRITE, refuseCommandName, } from "@wirecat/cli-core/cli";
|
|
5
|
+
import { answerStdinOption, commandWords, grantsAuthority, itemOf, LOCAL_READ, LOCAL_WRITE, logsInOrOut, NO_EFFECTS, privateFiles, REMOTE_WRITE, refuseCommandName, signInSteps, } from "@wirecat/cli-core/cli";
|
|
6
6
|
import { addStandardCommands } from "./commands.js";
|
|
7
7
|
import { addProfile, inspectConfig, setConfig, unsetConfig } from "./config.js";
|
|
8
8
|
import { publicIssue } from "./config-issues.js";
|
|
@@ -57,6 +57,7 @@ export const addConfigCommands = (program, { configPath, output, warn, named, })
|
|
|
57
57
|
output(itemOf(unsetConfig(configPath, key, named(), permissionKeys(program))));
|
|
58
58
|
});
|
|
59
59
|
};
|
|
60
|
+
const PASTE_PROMPT = "If the browser does not come back by itself, the address it ended on (code=…&state=…)";
|
|
60
61
|
/** The shared discovery, doctor and session status commands, plus Zoom's browser login. */
|
|
61
62
|
export const addSessionCommands = (program, context) => {
|
|
62
63
|
const { deps, getConfig, output, buffer, api, profile, tokens, fetch, signal } = context;
|
|
@@ -120,6 +121,7 @@ export const addSessionCommands = (program, context) => {
|
|
|
120
121
|
.command("start")
|
|
121
122
|
.description("log in to Zoom through your browser")
|
|
122
123
|
.option("--browser <program>", "browser program")
|
|
124
|
+
.addOption(answerStdinOption())
|
|
123
125
|
.action(async (opts) => {
|
|
124
126
|
const config = getConfig();
|
|
125
127
|
const selected = profile();
|
|
@@ -133,13 +135,26 @@ export const addSessionCommands = (program, context) => {
|
|
|
133
135
|
throw new CliError("configuration_error", "login requires browser approval; remove --no-input");
|
|
134
136
|
if (deps.env?.CI)
|
|
135
137
|
throw new CliError("configuration_error", `login requires browser approval; run zm ${selected} session start yourself`);
|
|
138
|
+
const steps = signInSteps({
|
|
139
|
+
diagnostic: (line) => deps.diagnostic(`${line}\n`),
|
|
140
|
+
json: globals.json === true || globals.jsonl === true,
|
|
141
|
+
answers: opts.answerStdin === true,
|
|
142
|
+
...(deps.stdin ? { input: deps.stdin } : {}),
|
|
143
|
+
});
|
|
136
144
|
const done = await login({
|
|
137
145
|
tokens: tokens(),
|
|
138
146
|
signal: signal(),
|
|
139
147
|
openBrowser: (url) => deps.openBrowser(url, opts.browser),
|
|
140
|
-
readPaste:
|
|
141
|
-
|
|
142
|
-
|
|
148
|
+
readPaste: steps.answers
|
|
149
|
+
? (stop) => steps
|
|
150
|
+
.ask({ field: "redirect", secret: true, prompt: PASTE_PROMPT }, stop)
|
|
151
|
+
// The browser's callback won the race; the question is withdrawn, not failed.
|
|
152
|
+
.catch((error) => (stop.aborted ? new Promise(() => { }) : Promise.reject(error)))
|
|
153
|
+
: deps.readPaste,
|
|
154
|
+
showUrl: (url) => steps.answers
|
|
155
|
+
? steps.openUrl(url, "Approve access to Zoom in the browser")
|
|
156
|
+
: // Without a terminal this line is all an agent can pass on, so --quiet keeps it.
|
|
157
|
+
deps.diagnostic(`Open this URL to approve Zoom login:\n${url}\n`),
|
|
143
158
|
});
|
|
144
159
|
addProfile(deps.configPath, selected);
|
|
145
160
|
output(itemOf({ ...done, profile: selected }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-commands.js","sourceRoot":"","sources":["../src/setup-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAqB,MAAM,mBAAmB,CAAA;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AACrD,OAAO,
|
|
1
|
+
{"version":3,"file":"setup-commands.js","sourceRoot":"","sources":["../src/setup-commands.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.
|
|
1
|
+
export declare const VERSION = "0.52.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = "0.
|
|
1
|
+
export const VERSION = "0.52.0";
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
import type * as T from "./types.js";
|
|
3
|
+
export declare const GetUserContactsResponse: v.GenericSchema<unknown, T.GetUserContactsResponse>;
|
|
4
|
+
export declare const GetUserContactResponse: v.GenericSchema<unknown, T.GetUserContactResponse>;
|
|
5
|
+
export declare const schemas: {
|
|
6
|
+
readonly GetUserContactsResponse: v.GenericSchema<unknown, T.GetUserContactsResponse>;
|
|
7
|
+
readonly GetUserContactResponse: v.GenericSchema<unknown, T.GetUserContactResponse>;
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/zoom-api/schemas.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,KAAK,KAAK,CAAC,MAAM,YAAY,CAAA;AAEpC,eAAO,MAAM,uBAAuB,EAAE,CAAC,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,uBAAuB,CActF,CAAA;AAEF,eAAO,MAAM,sBAAsB,EAAE,CAAC,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,sBAAsB,CAkCpF,CAAA;AAEF,eAAO,MAAM,OAAO;;;CAGV,CAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// GENERATED. DO NOT EDIT.
|
|
2
|
+
// Source: spec/zoom/chat.json
|
|
3
|
+
// Run: pnpm zoom:generate
|
|
4
|
+
import { integer } from "@wirecat/cli-base/codegen/runtime";
|
|
5
|
+
import * as v from "valibot";
|
|
6
|
+
export const GetUserContactsResponse = v.looseObject({
|
|
7
|
+
contacts: v.optional(v.array(v.looseObject({
|
|
8
|
+
email: v.optional(v.string()),
|
|
9
|
+
first_name: v.optional(v.string()),
|
|
10
|
+
id: v.optional(v.string()),
|
|
11
|
+
member_id: v.optional(v.string()),
|
|
12
|
+
last_name: v.optional(v.string()),
|
|
13
|
+
}))),
|
|
14
|
+
next_page_token: v.optional(v.string()),
|
|
15
|
+
page_size: v.optional(integer({ maximum: 1000 })),
|
|
16
|
+
});
|
|
17
|
+
export const GetUserContactResponse = v.looseObject({
|
|
18
|
+
direct_numbers: v.optional(v.array(v.string())),
|
|
19
|
+
email: v.optional(v.string()),
|
|
20
|
+
extension_number: v.optional(v.string()),
|
|
21
|
+
first_name: v.optional(v.string()),
|
|
22
|
+
id: v.optional(v.string()),
|
|
23
|
+
member_id: v.optional(v.string()),
|
|
24
|
+
last_name: v.optional(v.string()),
|
|
25
|
+
phone_number: v.optional(v.string()),
|
|
26
|
+
phone_numbers: v.optional(v.array(v.looseObject({
|
|
27
|
+
code: v.optional(v.string()),
|
|
28
|
+
country: v.optional(v.string()),
|
|
29
|
+
label: v.optional(v.picklist(["Mobile", "Office", "Home", "Fax"])),
|
|
30
|
+
number: v.optional(v.string()),
|
|
31
|
+
verified: v.optional(v.boolean()),
|
|
32
|
+
}))),
|
|
33
|
+
presence_status: v.optional(v.picklist([
|
|
34
|
+
"Do_Not_Disturb",
|
|
35
|
+
"Away",
|
|
36
|
+
"Available",
|
|
37
|
+
"Offline",
|
|
38
|
+
"In_A_Meeting",
|
|
39
|
+
"In_A_Call",
|
|
40
|
+
"In_A_Calendar_Event",
|
|
41
|
+
"Presenting",
|
|
42
|
+
"Out_of_Office",
|
|
43
|
+
"Busy",
|
|
44
|
+
])),
|
|
45
|
+
});
|
|
46
|
+
export const schemas = {
|
|
47
|
+
GetUserContactsResponse,
|
|
48
|
+
GetUserContactResponse,
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/zoom-api/schemas.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export type GetUserContactsResponse = {
|
|
2
|
+
/** The contacts object. */
|
|
3
|
+
contacts?: Array<{
|
|
4
|
+
/** Contact's email address. */
|
|
5
|
+
email?: string;
|
|
6
|
+
/** Contact's first name. */
|
|
7
|
+
first_name?: string;
|
|
8
|
+
/** The contact's user ID. If the user ID does not belong to the same account as the current user, this field will be empty. */
|
|
9
|
+
id?: string;
|
|
10
|
+
/** The contact's member ID. */
|
|
11
|
+
member_id?: string;
|
|
12
|
+
/** Contact's last name. */
|
|
13
|
+
last_name?: string;
|
|
14
|
+
}>;
|
|
15
|
+
/** The next page token is used to paginate through large result sets. A next page token will be returned whenever the set of available results exceeds the current page size. The expiration period for this token is 15 minutes. */
|
|
16
|
+
next_page_token?: string;
|
|
17
|
+
/** The number of records returned with a single API call. */
|
|
18
|
+
page_size?: number;
|
|
19
|
+
};
|
|
20
|
+
export type GetUserContactResponse = {
|
|
21
|
+
/** A list of direct numbers assigned to the contact. */
|
|
22
|
+
direct_numbers?: Array<string>;
|
|
23
|
+
/** The contact's email address. */
|
|
24
|
+
email?: string;
|
|
25
|
+
/** The extension number of the contact. */
|
|
26
|
+
extension_number?: string;
|
|
27
|
+
/** The contact's first name */
|
|
28
|
+
first_name?: string;
|
|
29
|
+
/** The contact's user ID. If the user ID does not belong to the same account as the current user, this field will be empty. */
|
|
30
|
+
id?: string;
|
|
31
|
+
/** The contact's member ID. */
|
|
32
|
+
member_id?: string;
|
|
33
|
+
/** The contact's last name. */
|
|
34
|
+
last_name?: string;
|
|
35
|
+
/** The phone number of the contact. */
|
|
36
|
+
phone_number?: string;
|
|
37
|
+
phone_numbers?: Array<{
|
|
38
|
+
/** The phone number's country code. For example, the country code for phone numbers in the United States is `+1`. */
|
|
39
|
+
code?: string;
|
|
40
|
+
/** The phone number's [country ID](https://marketplace.zoom.us/docs/api-reference/other-references/abbreviation-lists#countries). For example, if the phone number provided in the `number` field is a Brazil-based number, the value is `BR`. */
|
|
41
|
+
country?: string;
|
|
42
|
+
/** The phone number's label: * `Mobile` * `Office` * `Home` * `Fax` */
|
|
43
|
+
label?: "Mobile" | "Office" | "Home" | "Fax";
|
|
44
|
+
/** The user's phone number. */
|
|
45
|
+
number?: string;
|
|
46
|
+
/** Whether Zoom has verified the phone number. */
|
|
47
|
+
verified?: boolean;
|
|
48
|
+
}>;
|
|
49
|
+
/** The contact's presence status in the Zoom Chat client. The status can be one of the following: `Do_Not_Disturb` `Away` `Available` `Offline` `In_A_Meeting` `In_A_Call` `In_A_Calendar_Event` `Presenting` `Out_of_Office` `Busy` */
|
|
50
|
+
presence_status?: "Do_Not_Disturb" | "Away" | "Available" | "Offline" | "In_A_Meeting" | "In_A_Call" | "In_A_Calendar_Event" | "Presenting" | "Out_of_Office" | "Busy";
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/zoom-api/types.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,uBAAuB,GAAG;IACpC,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,KAAK,CAAC;QACf,+BAA+B;QAC/B,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,4BAA4B;QAC5B,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,+HAA+H;QAC/H,EAAE,CAAC,EAAE,MAAM,CAAA;QACX,+BAA+B;QAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,2BAA2B;QAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;KACnB,CAAC,CAAA;IACF,qOAAqO;IACrO,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,wDAAwD;IACxD,cAAc,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IAC9B,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2CAA2C;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,+BAA+B;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,+HAA+H;IAC/H,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,KAAK,CAAC;QACpB,qHAAqH;QACrH,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,kPAAkP;QAClP,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,uEAAuE;QACvE,KAAK,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAA;QAC5C,+BAA+B;QAC/B,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,kDAAkD;QAClD,QAAQ,CAAC,EAAE,OAAO,CAAA;KACnB,CAAC,CAAA;IACF,wOAAwO;IACxO,eAAe,CAAC,EACZ,gBAAgB,GAChB,MAAM,GACN,WAAW,GACX,SAAS,GACT,cAAc,GACd,WAAW,GACX,qBAAqB,GACrB,YAAY,GACZ,eAAe,GACf,MAAM,CAAA;CACX,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/zoom-api/types.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,8BAA8B;AAC9B,0BAA0B"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { TokenManager } from "./tokens.js";
|
|
2
|
+
export declare const ZOOM_MCP_URL = "https://mcp.zoom.us/mcp/zoom/streamable";
|
|
3
|
+
/** Zoom's hosted MCP server, called with the profile's own login; one session per instance. */
|
|
4
|
+
export declare class ZoomMcp {
|
|
5
|
+
readonly tokens: Pick<TokenManager, "tokens">;
|
|
6
|
+
readonly fetcher: typeof fetch;
|
|
7
|
+
private session;
|
|
8
|
+
private initialized;
|
|
9
|
+
private id;
|
|
10
|
+
constructor(tokens: Pick<TokenManager, "tokens">, fetcher: typeof fetch);
|
|
11
|
+
call(tool: string, args: Record<string, unknown>, scope: string, signal?: AbortSignal): Promise<unknown>;
|
|
12
|
+
private rpc;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=zoom-mcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zoom-mcp.d.ts","sourceRoot":"","sources":["../src/zoom-mcp.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C,eAAO,MAAM,YAAY,4CAA4C,CAAA;AAOrE,+FAA+F;AAC/F,qBAAa,OAAO;IAKhB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE,OAAO,KAAK;IALhC,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,EAAE,CAAI;IACd,YACW,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,EACpC,OAAO,EAAE,OAAO,KAAK,EAC5B;IAEE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAwB7G;YAEa,GAAG;CAwClB"}
|
package/dist/zoom-mcp.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { CliError } from "@wirecat/cli-base";
|
|
2
|
+
import { checkCancelled, object } from "./errors.js";
|
|
3
|
+
import { operationSignal } from "./remote-http.js";
|
|
4
|
+
export const ZOOM_MCP_URL = "https://mcp.zoom.us/mcp/zoom/streamable";
|
|
5
|
+
const PROTOCOL = "2025-06-18";
|
|
6
|
+
const record = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7
|
+
const sessionStart = (scope) => `add ${scope} to the app and run zm <profile> session start again`;
|
|
8
|
+
/** Zoom's hosted MCP server, called with the profile's own login; one session per instance. */
|
|
9
|
+
export class ZoomMcp {
|
|
10
|
+
tokens;
|
|
11
|
+
fetcher;
|
|
12
|
+
session;
|
|
13
|
+
initialized = false;
|
|
14
|
+
id = 0;
|
|
15
|
+
constructor(tokens, fetcher) {
|
|
16
|
+
this.tokens = tokens;
|
|
17
|
+
this.fetcher = fetcher;
|
|
18
|
+
}
|
|
19
|
+
async call(tool, args, scope, signal) {
|
|
20
|
+
const operation = operationSignal(signal);
|
|
21
|
+
const { accessToken, scopes } = await this.tokens.tokens();
|
|
22
|
+
if (!scopes.includes(scope))
|
|
23
|
+
throw new CliError("configuration_error", `Zoom scope ${scope} is missing; ${sessionStart(scope)}`);
|
|
24
|
+
if (!this.initialized) {
|
|
25
|
+
await this.rpc("initialize", accessToken, operation, {
|
|
26
|
+
protocolVersion: PROTOCOL,
|
|
27
|
+
capabilities: {},
|
|
28
|
+
clientInfo: { name: "zm", version: "1" },
|
|
29
|
+
});
|
|
30
|
+
await this.rpc("notifications/initialized", accessToken, operation, {});
|
|
31
|
+
this.initialized = true;
|
|
32
|
+
}
|
|
33
|
+
const result = object(await this.rpc("tools/call", accessToken, operation, { name: tool, arguments: args }));
|
|
34
|
+
const content = Array.isArray(result.content) ? result.content : [];
|
|
35
|
+
const text = content.find((part) => record(part) && typeof part.text === "string")?.text;
|
|
36
|
+
if (result.isError === true)
|
|
37
|
+
throw toolError(text);
|
|
38
|
+
if (record(result.structuredContent))
|
|
39
|
+
return result.structuredContent;
|
|
40
|
+
try {
|
|
41
|
+
return JSON.parse(text ?? "");
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
throw new CliError("invalid_response", `Zoom returned an invalid ${tool} answer`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async rpc(method, accessToken, signal, params) {
|
|
48
|
+
checkCancelled(signal);
|
|
49
|
+
const notification = method.startsWith("notifications/");
|
|
50
|
+
const id = notification ? undefined : ++this.id;
|
|
51
|
+
let response;
|
|
52
|
+
try {
|
|
53
|
+
response = await this.fetcher(ZOOM_MCP_URL, {
|
|
54
|
+
method: "POST",
|
|
55
|
+
headers: {
|
|
56
|
+
authorization: `Bearer ${accessToken}`,
|
|
57
|
+
"content-type": "application/json",
|
|
58
|
+
accept: "application/json, text/event-stream",
|
|
59
|
+
...(this.session ? { "mcp-session-id": this.session } : {}),
|
|
60
|
+
},
|
|
61
|
+
body: JSON.stringify({ jsonrpc: "2.0", ...(id === undefined ? {} : { id }), method, params }),
|
|
62
|
+
redirect: "manual",
|
|
63
|
+
signal,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
checkCancelled(signal);
|
|
68
|
+
throw new CliError("network_error", "Zoom search could not be reached");
|
|
69
|
+
}
|
|
70
|
+
this.session = response.headers.get("mcp-session-id") ?? this.session;
|
|
71
|
+
const text = await response.text();
|
|
72
|
+
const message = parseMessage(text, response.headers.get("content-type"), id);
|
|
73
|
+
if (response.status === 401)
|
|
74
|
+
throw new CliError("authentication_error", "Zoom refused the login; run zm <profile> session start again");
|
|
75
|
+
// Zoom answers a missing scope with 403 and JSON-RPC error -32003 naming the scopes it wants.
|
|
76
|
+
if (response.status === 403 && record(message?.error) && message.error.code === -32003)
|
|
77
|
+
throw new CliError("configuration_error", `Zoom wants scope ${String(message.error.message)}; ${sessionStart("it")}`);
|
|
78
|
+
if (!response.ok)
|
|
79
|
+
throw new CliError("provider_error", `Zoom search failed (HTTP ${response.status})`);
|
|
80
|
+
if (notification)
|
|
81
|
+
return undefined;
|
|
82
|
+
if (!message)
|
|
83
|
+
throw new CliError("invalid_response", "Zoom returned an invalid search answer");
|
|
84
|
+
if (record(message.error))
|
|
85
|
+
throw new CliError("provider_error", `Zoom search failed: ${String(message.error.message ?? "unknown error")}`);
|
|
86
|
+
return message.result;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const parseMessage = (text, type, id) => {
|
|
90
|
+
const parse = (body) => {
|
|
91
|
+
try {
|
|
92
|
+
const value = JSON.parse(body);
|
|
93
|
+
return record(value) ? value : undefined;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
if (!type?.includes("text/event-stream"))
|
|
100
|
+
return text ? parse(text) : undefined;
|
|
101
|
+
const messages = text
|
|
102
|
+
.split("\n")
|
|
103
|
+
.filter((line) => line.startsWith("data:"))
|
|
104
|
+
.map((line) => parse(line.slice(5).trim()));
|
|
105
|
+
return messages.find((value) => value && value.id === id) ?? messages.findLast((value) => value !== undefined);
|
|
106
|
+
};
|
|
107
|
+
/** Zoom puts a refused tool call (no license, no access) in the result text as JSON. */
|
|
108
|
+
const toolError = (text) => {
|
|
109
|
+
let body = {};
|
|
110
|
+
try {
|
|
111
|
+
const value = JSON.parse(text?.replace(/^[^{]*/, "") ?? "");
|
|
112
|
+
if (record(value))
|
|
113
|
+
body = value;
|
|
114
|
+
}
|
|
115
|
+
catch { }
|
|
116
|
+
const reason = typeof body.error_message === "string" ? body.error_message : (text ?? "").slice(0, 200);
|
|
117
|
+
const status = typeof body.status_code === "number" ? body.status_code : null;
|
|
118
|
+
return new CliError(status === 403 ? "permission_error" : status === 404 ? "not_found" : "invalid_response", `Zoom refused the request: ${reason || "no reason given"}`);
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=zoom-mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zoom-mcp.js","sourceRoot":"","sources":["../src/zoom-mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Body } from "@wirecat/cli-core/cli";
|
|
2
|
+
import type { Command } from "commander";
|
|
3
|
+
import { type ZoomSearch } from "./zoom-search.js";
|
|
4
|
+
export type ZoomSearchService = Pick<ZoomSearch, "search">;
|
|
5
|
+
export declare const addZoomSearchCommands: (program: Command, deps: {
|
|
6
|
+
search: () => ZoomSearchService;
|
|
7
|
+
api: () => void;
|
|
8
|
+
signal: () => AbortSignal | undefined;
|
|
9
|
+
output: (body: Body) => void;
|
|
10
|
+
}) => void;
|
|
11
|
+
//# sourceMappingURL=zoom-search-commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zoom-search-commands.d.ts","sourceRoot":"","sources":["../src/zoom-search-commands.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,IAAI,EAAmC,MAAM,uBAAuB,CAAA;AAClF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAuB,KAAK,UAAU,EAAyB,MAAM,kBAAkB,CAAA;AAE9F,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;AAmB1D,eAAO,MAAM,qBAAqB,YACvB,OAAO,QACV;IACJ,MAAM,EAAE,MAAM,iBAAiB,CAAA;IAC/B,GAAG,EAAE,MAAM,IAAI,CAAA;IACf,MAAM,EAAE,MAAM,WAAW,GAAG,SAAS,CAAA;IACrC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAA;CAC7B,KACA,IAwCF,CAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { CliError } from "@wirecat/cli-base";
|
|
2
|
+
import { annotate } from "@wirecat/cli-base/commands";
|
|
3
|
+
import { listOf, NO_EFFECTS, REMOTE_READ } from "@wirecat/cli-core/cli";
|
|
4
|
+
import { ZOOM_SEARCH_SOURCES } from "./zoom-search.js";
|
|
5
|
+
const WORDS = Object.keys(ZOOM_SEARCH_SOURCES);
|
|
6
|
+
const sourcesOf = (text) => {
|
|
7
|
+
if (text === undefined)
|
|
8
|
+
return undefined;
|
|
9
|
+
const words = text.split(",").map((word) => word.trim().toLowerCase());
|
|
10
|
+
const unknown = words.filter((word) => !WORDS.includes(word));
|
|
11
|
+
if (!words.length || unknown.length)
|
|
12
|
+
throw new CliError("validation_error", `--only takes ${WORDS.join(", ")}; got ${unknown.join(", ") || "nothing"}`);
|
|
13
|
+
return [...new Set(words)];
|
|
14
|
+
};
|
|
15
|
+
const limitOf = (text) => {
|
|
16
|
+
if (text === undefined)
|
|
17
|
+
return 10;
|
|
18
|
+
const value = Number(text);
|
|
19
|
+
if (!/^\d+$/.test(text) || value < 1 || value > 100)
|
|
20
|
+
throw new CliError("validation_error", "--limit must be between 1 and 100");
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
export const addZoomSearchCommands = (program, deps) => {
|
|
24
|
+
const zoom = annotate(program.command("zoom"), { effects: NO_EFFECTS }).description("Zoom's own live search: chat, docs and meetings zm does not archive");
|
|
25
|
+
annotate(zoom.command("search"), {
|
|
26
|
+
origin: "handwritten",
|
|
27
|
+
effects: REMOTE_READ,
|
|
28
|
+
examples: [
|
|
29
|
+
'zm personal zoom search "budget" --only chat,docs --json',
|
|
30
|
+
"zm personal zoom search --only meetings --limit 50",
|
|
31
|
+
],
|
|
32
|
+
})
|
|
33
|
+
.description("search your Zoom workspace live; without words, list recent records")
|
|
34
|
+
.argument("[query]", "words Zoom matches in the content; it does not widen word forms")
|
|
35
|
+
.option("--only <resources>", `comma list of ${WORDS.join(", ")} (default Zoom's own choice)`)
|
|
36
|
+
.option("--limit <n>", "Zoom results per resource, 1 through 100 (default 10); one chat result holds its matching messages")
|
|
37
|
+
.option("--cursor <cursor>", "continue from the previous page's page.next_cursor, with the same query and --only")
|
|
38
|
+
.action(async (query, options) => {
|
|
39
|
+
const sources = sourcesOf(options.only);
|
|
40
|
+
const limit = limitOf(options.limit);
|
|
41
|
+
deps.api();
|
|
42
|
+
const page = await deps.search().search({ query, sources, limit, cursor: options.cursor, signal: deps.signal() });
|
|
43
|
+
deps.output(listOf("zoom search", {
|
|
44
|
+
items: page.items,
|
|
45
|
+
limit: Math.max(1, page.items.length),
|
|
46
|
+
has_more: page.has_more,
|
|
47
|
+
paging: "cursor",
|
|
48
|
+
...(page.cursor ? { cursor: page.cursor } : {}),
|
|
49
|
+
args: {
|
|
50
|
+
...(query === undefined ? {} : { query }),
|
|
51
|
+
...(options.only === undefined ? {} : { only: options.only }),
|
|
52
|
+
limit,
|
|
53
|
+
},
|
|
54
|
+
}));
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=zoom-search-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zoom-search-commands.js","sourceRoot":"","sources":["../src/zoom-search-commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { TokenManager } from "./tokens.js";
|
|
2
|
+
import { ZoomMcp } from "./zoom-mcp.js";
|
|
3
|
+
export declare const ZOOM_SEARCH_SCOPE = "agentic_search:read:search";
|
|
4
|
+
/** Our words for Zoom's datasources. */
|
|
5
|
+
export declare const ZOOM_SEARCH_SOURCES: {
|
|
6
|
+
readonly meetings: "zoom_meeting";
|
|
7
|
+
readonly calendar: "calendar";
|
|
8
|
+
readonly chat: "zoom_chat_message";
|
|
9
|
+
readonly channels: "zoom_chat_session";
|
|
10
|
+
readonly docs: "zoom_canvas";
|
|
11
|
+
readonly notes: "zoom_my_notes";
|
|
12
|
+
readonly calls: "zoom_phone_call";
|
|
13
|
+
readonly sms: "zoom_phone_sms";
|
|
14
|
+
readonly voicemail: "zoom_phone_voicemail";
|
|
15
|
+
};
|
|
16
|
+
export type ZoomSearchSource = keyof typeof ZOOM_SEARCH_SOURCES;
|
|
17
|
+
export interface ZoomSearchHit {
|
|
18
|
+
source: string;
|
|
19
|
+
id: string | null;
|
|
20
|
+
title: string | null;
|
|
21
|
+
time: string | null;
|
|
22
|
+
text: string | null;
|
|
23
|
+
url: string | null;
|
|
24
|
+
people: string[];
|
|
25
|
+
/** The chat a message is in. */
|
|
26
|
+
container_id: string | null;
|
|
27
|
+
details: Record<string, string | number | boolean | null>;
|
|
28
|
+
}
|
|
29
|
+
export interface ZoomSearchPage {
|
|
30
|
+
items: ZoomSearchHit[];
|
|
31
|
+
has_more: boolean;
|
|
32
|
+
cursor?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface ZoomSearchRequest {
|
|
35
|
+
query?: string;
|
|
36
|
+
sources?: ZoomSearchSource[];
|
|
37
|
+
limit?: number;
|
|
38
|
+
cursor?: string;
|
|
39
|
+
signal?: AbortSignal;
|
|
40
|
+
}
|
|
41
|
+
/** One Zoom row can be one chat holding several matching messages; each message is its own hit. */
|
|
42
|
+
export declare const zoomSearchHits: (rows: unknown[]) => ZoomSearchHit[];
|
|
43
|
+
export declare class ZoomSearch {
|
|
44
|
+
readonly mcp: ZoomMcp;
|
|
45
|
+
constructor(tokens: Pick<TokenManager, "tokens">, fetcher: typeof fetch);
|
|
46
|
+
search(request: ZoomSearchRequest): Promise<ZoomSearchPage>;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=zoom-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zoom-search.d.ts","sourceRoot":"","sources":["../src/zoom-search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,eAAO,MAAM,iBAAiB,+BAA+B,CAAA;AAC7D,wCAAwC;AACxC,eAAO,MAAM,mBAAmB;aAC9B,QAAQ,EAAE,cAAc;aACxB,QAAQ,EAAE,UAAU;aACpB,IAAI,EAAE,mBAAmB;aACzB,QAAQ,EAAE,mBAAmB;aAC7B,IAAI,EAAE,aAAa;aACnB,KAAK,EAAE,eAAe;aACtB,KAAK,EAAE,iBAAiB;aACxB,GAAG,EAAE,gBAAgB;aACrB,SAAS,EAAE,sBAAsB;CACzB,CAAA;AACV,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,mBAAmB,CAAA;AAG/D,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,gCAAgC;IAChC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAA;CAC1D;AACD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,aAAa,EAAE,CAAA;IACtB,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AACD,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAwDD,mGAAmG;AACnG,eAAO,MAAM,cAAc,SAAU,OAAO,EAAE,KAAG,aAAa,EAa1D,CAAA;AAEJ,qBAAa,UAAU;IACrB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAA;IACrB,YAAY,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,OAAO,KAAK,EAEtE;IACK,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CAWhE;CACF"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { CliError } from "@wirecat/cli-base";
|
|
2
|
+
import { ZoomMcp } from "./zoom-mcp.js";
|
|
3
|
+
export const ZOOM_SEARCH_SCOPE = "agentic_search:read:search";
|
|
4
|
+
/** Our words for Zoom's datasources. */
|
|
5
|
+
export const ZOOM_SEARCH_SOURCES = {
|
|
6
|
+
meetings: "zoom_meeting",
|
|
7
|
+
calendar: "calendar",
|
|
8
|
+
chat: "zoom_chat_message",
|
|
9
|
+
channels: "zoom_chat_session",
|
|
10
|
+
docs: "zoom_canvas",
|
|
11
|
+
notes: "zoom_my_notes",
|
|
12
|
+
calls: "zoom_phone_call",
|
|
13
|
+
sms: "zoom_phone_sms",
|
|
14
|
+
voicemail: "zoom_phone_voicemail",
|
|
15
|
+
};
|
|
16
|
+
const SOURCE_OF = new Map(Object.entries(ZOOM_SEARCH_SOURCES).map(([word, name]) => [name, word]));
|
|
17
|
+
const record = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18
|
+
const filled = (value) => typeof value === "string" && value.trim() !== "";
|
|
19
|
+
const first = (row, keys) => keys.map((key) => row[key]).find(filled) ?? null;
|
|
20
|
+
const ID_KEYS = ["meeting_uuid", "message_id", "session_id", "file_id", "note_id", "call_id", "event_id", "id"];
|
|
21
|
+
const TITLE_KEYS = ["topic", "title", "session_name", "subject", "name", "file_name"];
|
|
22
|
+
const TIME_KEYS = ["meeting_start_time", "sent_time", "start_time", "modify_time", "created_time", "create_time"];
|
|
23
|
+
const CHUNK_KEYS = ["chunks", "call_summary_chunks", "transcript_chunks"];
|
|
24
|
+
const chunkText = (row) => {
|
|
25
|
+
const parts = CHUNK_KEYS.flatMap((key) => (Array.isArray(row[key]) ? row[key] : [])).flatMap((chunk) => {
|
|
26
|
+
if (filled(chunk))
|
|
27
|
+
return [chunk];
|
|
28
|
+
if (record(chunk))
|
|
29
|
+
return [first(chunk, ["text", "content", "chunk"])].filter(filled);
|
|
30
|
+
return [];
|
|
31
|
+
});
|
|
32
|
+
return parts.length ? parts.join("\n") : null;
|
|
33
|
+
};
|
|
34
|
+
const peopleOf = (row) => {
|
|
35
|
+
const list = Array.isArray(row.attendees) ? row.attendees : Array.isArray(row.attendee_list) ? row.attendee_list : [];
|
|
36
|
+
return list.flatMap((person) => {
|
|
37
|
+
const name = record(person) ? first(person, ["display_name", "user_name", "name"]) : null;
|
|
38
|
+
return name ? [name] : [];
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
const hitOf = (row, source, container = null) => {
|
|
42
|
+
const id = first(row, ID_KEYS) ??
|
|
43
|
+
Object.entries(row).find(([key, value]) => key.endsWith("_id") && filled(value))?.[1] ??
|
|
44
|
+
null;
|
|
45
|
+
const time = first(row, TIME_KEYS) ??
|
|
46
|
+
Object.entries(row).find(([key, value]) => key.endsWith("_time") && filled(value))?.[1] ??
|
|
47
|
+
null;
|
|
48
|
+
const details = {};
|
|
49
|
+
for (const [key, value] of Object.entries(row))
|
|
50
|
+
if (key !== "datasource" && (value === null || ["string", "number", "boolean"].includes(typeof value)))
|
|
51
|
+
details[key] = value;
|
|
52
|
+
return {
|
|
53
|
+
source,
|
|
54
|
+
id,
|
|
55
|
+
title: first(row, TITLE_KEYS),
|
|
56
|
+
time,
|
|
57
|
+
text: first(row, ["message", "text", "snippet"]) ?? chunkText(row),
|
|
58
|
+
url: first(row, ["link", "url", "join_url"]),
|
|
59
|
+
people: peopleOf(row),
|
|
60
|
+
container_id: container,
|
|
61
|
+
details,
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
/** One Zoom row can be one chat holding several matching messages; each message is its own hit. */
|
|
65
|
+
export const zoomSearchHits = (rows) => rows.flatMap((row) => {
|
|
66
|
+
if (!record(row))
|
|
67
|
+
throw new CliError("invalid_response", "Zoom returned an invalid search result");
|
|
68
|
+
const name = filled(row.datasource) ? row.datasource : "unknown";
|
|
69
|
+
const source = SOURCE_OF.get(name) ?? name;
|
|
70
|
+
if (name === "zoom_chat_message" && Array.isArray(row.messages)) {
|
|
71
|
+
const chat = filled(row.session_id) ? row.session_id : null;
|
|
72
|
+
return row.messages.filter(record).map((message) => {
|
|
73
|
+
const hit = hitOf(message, source, chat);
|
|
74
|
+
return { ...hit, title: hit.title ?? first(row, ["session_name"]) };
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return [hitOf(row, source)];
|
|
78
|
+
});
|
|
79
|
+
export class ZoomSearch {
|
|
80
|
+
mcp;
|
|
81
|
+
constructor(tokens, fetcher) {
|
|
82
|
+
this.mcp = new ZoomMcp(tokens, fetcher);
|
|
83
|
+
}
|
|
84
|
+
async search(request) {
|
|
85
|
+
const args = { page_size: request.limit ?? 10 };
|
|
86
|
+
if (request.query?.trim())
|
|
87
|
+
args.query = request.query.trim();
|
|
88
|
+
if (request.sources?.length)
|
|
89
|
+
args.datasource_filters = request.sources.map((source) => ({ datasource: ZOOM_SEARCH_SOURCES[source] }));
|
|
90
|
+
if (request.cursor)
|
|
91
|
+
args.next_page_token = request.cursor;
|
|
92
|
+
const body = await this.mcp.call("search", args, ZOOM_SEARCH_SCOPE, request.signal);
|
|
93
|
+
if (!record(body) || !Array.isArray(body.data))
|
|
94
|
+
throw new CliError("invalid_response", "Zoom returned an invalid search answer");
|
|
95
|
+
const cursor = filled(body.next_page_token) ? body.next_page_token : undefined;
|
|
96
|
+
return { items: zoomSearchHits(body.data), has_more: body.has_more === true, ...(cursor ? { cursor } : {}) };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=zoom-search.js.map
|