@wirecat/zoom-cli 0.2.2 → 0.3.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 (59) hide show
  1. package/README.md +98 -3
  2. package/dist/archive-import.d.ts +27 -0
  3. package/dist/archive-import.d.ts.map +1 -0
  4. package/dist/archive-import.js +125 -0
  5. package/dist/archive-import.js.map +1 -0
  6. package/dist/archive-transcripts.d.ts.map +1 -1
  7. package/dist/archive-transcripts.js +3 -3
  8. package/dist/archive-transcripts.js.map +1 -1
  9. package/dist/bin/zm.js +6 -1
  10. package/dist/bin/zm.js.map +1 -1
  11. package/dist/index.d.ts +5 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +4 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/ingestion-search-commands.d.ts +15 -0
  16. package/dist/ingestion-search-commands.d.ts.map +1 -0
  17. package/dist/ingestion-search-commands.js +66 -0
  18. package/dist/ingestion-search-commands.js.map +1 -0
  19. package/dist/mcp-server.d.ts +6 -0
  20. package/dist/mcp-server.d.ts.map +1 -1
  21. package/dist/mcp-server.js +209 -6
  22. package/dist/mcp-server.js.map +1 -1
  23. package/dist/meeting-context-commands.d.ts +8 -0
  24. package/dist/meeting-context-commands.d.ts.map +1 -0
  25. package/dist/meeting-context-commands.js +77 -0
  26. package/dist/meeting-context-commands.js.map +1 -0
  27. package/dist/meeting-context.d.ts +30 -0
  28. package/dist/meeting-context.d.ts.map +1 -0
  29. package/dist/meeting-context.js +119 -0
  30. package/dist/meeting-context.js.map +1 -0
  31. package/dist/meeting-semantic-commands.d.ts +38 -0
  32. package/dist/meeting-semantic-commands.d.ts.map +1 -0
  33. package/dist/meeting-semantic-commands.js +98 -0
  34. package/dist/meeting-semantic-commands.js.map +1 -0
  35. package/dist/meeting-semantic.d.ts +10 -0
  36. package/dist/meeting-semantic.d.ts.map +1 -0
  37. package/dist/meeting-semantic.js +70 -0
  38. package/dist/meeting-semantic.js.map +1 -0
  39. package/dist/ordinary-file.d.ts +4 -0
  40. package/dist/ordinary-file.d.ts.map +1 -0
  41. package/dist/ordinary-file.js +51 -0
  42. package/dist/ordinary-file.js.map +1 -0
  43. package/dist/program.d.ts +16 -1
  44. package/dist/program.d.ts.map +1 -1
  45. package/dist/program.js +138 -9
  46. package/dist/program.js.map +1 -1
  47. package/dist/recording-archive.d.ts.map +1 -1
  48. package/dist/recording-archive.js +2 -6
  49. package/dist/recording-archive.js.map +1 -1
  50. package/dist/store-connection.d.ts +1 -1
  51. package/dist/store-connection.d.ts.map +1 -1
  52. package/dist/store-connection.js +39 -2
  53. package/dist/store-connection.js.map +1 -1
  54. package/dist/unified-search.d.ts +6 -0
  55. package/dist/unified-search.d.ts.map +1 -0
  56. package/dist/unified-search.js +58 -0
  57. package/dist/unified-search.js.map +1 -0
  58. package/package.json +15 -7
  59. package/skills/zoom-cli/SKILL.md +54 -4
@@ -0,0 +1,98 @@
1
+ import { annotate } from "@wirecat/cli-core/commands";
2
+ import { ZoomError } from "./errors.js";
3
+ import { bytes } from "./execution.js";
4
+ const bounded = (value, maximum) => value === undefined || (Number.isSafeInteger(value) && value > 0 && value <= maximum);
5
+ export const validateMeetingModel = (options) => {
6
+ if (typeof options.model !== "string" || !options.model.trim() || options.model.length > 1000)
7
+ throw new ZoomError("validation_error", "select an explicit embedding model");
8
+ if (options.baseUrl === undefined) {
9
+ if (options.dims !== undefined)
10
+ throw new ZoomError("validation_error", "dimensions require an explicit remote base URL");
11
+ return;
12
+ }
13
+ let url;
14
+ try {
15
+ url = new URL(options.baseUrl);
16
+ }
17
+ catch {
18
+ throw new ZoomError("validation_error", "embedding base URL must be an HTTP or HTTPS URL");
19
+ }
20
+ if (!["http:", "https:"].includes(url.protocol) ||
21
+ url.username ||
22
+ url.password ||
23
+ url.search ||
24
+ url.hash ||
25
+ !/^[\w./:-]{1,200}$/.test(options.model) ||
26
+ options.dims === undefined ||
27
+ !bounded(options.dims, 8192))
28
+ throw new ZoomError("validation_error", "remote embeddings require an HTTP base URL without credentials and explicit dimensions");
29
+ };
30
+ export const validateMeetingSemantic = (query, options) => {
31
+ validateMeetingModel(options);
32
+ if (typeof query !== "string" ||
33
+ !query.trim() ||
34
+ Buffer.byteLength(query, "utf8") > 65536 ||
35
+ !bounded(options.limit, 1000) ||
36
+ !bounded(options.maxChunks, 10000) ||
37
+ !bounded(options.afterChunkId, Number.MAX_SAFE_INTEGER) ||
38
+ !bounded(options.maxRows, 100000) ||
39
+ !bounded(options.maxTextBytes, 64 * 1024 * 1024))
40
+ throw new ZoomError("validation_error", "meeting semantic search requires a nonempty bounded query and positive limits");
41
+ };
42
+ export const validateMeetingEmbeddings = (options) => {
43
+ validateMeetingModel(options);
44
+ if (!bounded(options.limit, 1000) ||
45
+ !bounded(options.afterTranscriptId, Number.MAX_SAFE_INTEGER) ||
46
+ !bounded(options.maxRows, 100000) ||
47
+ !bounded(options.maxTextBytes, 64 * 1024 * 1024) ||
48
+ (options.afterHash !== undefined && !/^[a-f0-9]{64}$/.test(options.afterHash)))
49
+ throw new ZoomError("validation_error", "meeting embedding generation requires valid bounded limits and cursors");
50
+ };
51
+ export const addMeetingSemanticCommands = (program, deps) => {
52
+ const meetings = program.commands.find((command) => command.name() === "meetings");
53
+ if (!meetings)
54
+ throw new ZoomError("configuration_error", "meeting command group is unavailable");
55
+ const model = (command) => command
56
+ .requiredOption("--model <id>", "explicit installed local model ID, or model served at --base-url")
57
+ .option("--base-url <url>", "explicit remote endpoint; OpenAI uses OPENAI_API_KEY")
58
+ .option("--dims <count>", "remote embedding vector dimensions", bytes);
59
+ const budget = (command) => command
60
+ .option("--limit <count>", "bounded batch/result count from 1 through 1000", bytes)
61
+ .option("--max-rows <count>", "transcript cue read limit from 1 through 100000", bytes)
62
+ .option("--max-text-bytes <count>", "aggregate transcript text read byte limit (default 4 MiB)", bytes);
63
+ annotate(budget(model(meetings
64
+ .command("semantic")
65
+ .description("search stored meeting vectors with an explicit query model; ranks only scanned candidates")
66
+ .argument("<query>")))
67
+ .option("--max-chunks <count>", "embedded candidate scan bound", bytes)
68
+ .option("--after-chunk-id <id>", "candidate scan continuation; not globally ranked result pagination", bytes)
69
+ .action(async (query, options) => {
70
+ validateMeetingSemantic(query, options);
71
+ if (options.baseUrl !== undefined && deps.offline())
72
+ throw new ZoomError("configuration_error", "remote embeddings require network access; remove --offline");
73
+ const api = await deps.capabilities();
74
+ deps.output(await api.search(query, { ...options, signal: deps.signal() }));
75
+ }), {
76
+ origin: "handwritten",
77
+ mutates: false,
78
+ examples: ['zm meetings semantic "example plan" --model e5-small --json'],
79
+ });
80
+ annotate(budget(model(meetings
81
+ .command("embeddings")
82
+ .description("preview meeting vector generation; --yes explicitly rebuilds and embeds one bounded batch")))
83
+ .option("--after-transcript-id <id>", "transcript chunk rebuild continuation", bytes)
84
+ .option("--after-hash <hash>", "missing embedding batch continuation")
85
+ .option("--yes", "apply chunk rebuild and embedding generation; preview otherwise")
86
+ .action(async (options) => {
87
+ validateMeetingEmbeddings(options);
88
+ if (options.baseUrl !== undefined && deps.offline())
89
+ throw new ZoomError("configuration_error", "remote embeddings require network access; remove --offline");
90
+ const api = await deps.capabilities();
91
+ const result = await api.generate({ ...options, signal: deps.signal() });
92
+ if (options.yes)
93
+ await deps.receipt(result);
94
+ else
95
+ deps.output(result);
96
+ }), { origin: "handwritten", mutates: true, local: true, examples: ["zm meetings embeddings --model e5-small --json"] });
97
+ };
98
+ //# sourceMappingURL=meeting-semantic-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meeting-semantic-commands.js","sourceRoot":"","sources":["../src/meeting-semantic-commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { MeetingVectors } from "@wirecat/cli-messaging/store";
2
+ import { type MeetingSemanticCapabilities } from "./meeting-semantic-commands.js";
3
+ type ProducerSemanticApi = Pick<typeof import("@wirecat/cli-messaging/services"), "meetingEmbeddingModel" | "createMeetingRemoteModel" | "openMeetingEmbedder" | "readMeetingSemantic" | "proposeMeetingEmbedding" | "applyMeetingEmbedding">;
4
+ /** The connection selects the account; explicit command options select the model. */
5
+ export declare const createMeetingSemanticCapabilities: (vectors: MeetingVectors, accountId: number, options?: {
6
+ env?: NodeJS.ProcessEnv;
7
+ load?: () => Promise<ProducerSemanticApi>;
8
+ }) => MeetingSemanticCapabilities;
9
+ export {};
10
+ //# sourceMappingURL=meeting-semantic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meeting-semantic.d.ts","sourceRoot":"","sources":["../src/meeting-semantic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAElE,OAAO,EAGL,KAAK,2BAA2B,EAGjC,MAAM,gCAAgC,CAAA;AAEvC,KAAK,mBAAmB,GAAG,IAAI,CAC7B,cAAc,iCAAiC,CAAC,EAC9C,uBAAuB,GACvB,0BAA0B,GAC1B,qBAAqB,GACrB,qBAAqB,GACrB,yBAAyB,GACzB,uBAAuB,CAC1B,CAAA;AAED,qFAAqF;AACrF,eAAO,MAAM,iCAAiC,YACnC,cAAc,aACZ,MAAM,YACR;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAA;CAAE,KAC9E,2BA+DF,CAAA"}
@@ -0,0 +1,70 @@
1
+ import { checkCancelled, ZoomError } from "./errors.js";
2
+ import { validateMeetingEmbeddings, validateMeetingSemantic, } from "./meeting-semantic-commands.js";
3
+ const loadProducer = async () => import("@wirecat/cli-messaging/services");
4
+ /** The connection selects the account; explicit command options select the model. */
5
+ export const createMeetingSemanticCapabilities = (vectors, accountId, options = {}) => {
6
+ if (!Number.isSafeInteger(accountId) || accountId < 1)
7
+ throw new ZoomError("validation_error", "meeting vectors require a selected positive account ID");
8
+ const load = options.load ?? loadProducer;
9
+ const choice = (api, input) => input.baseUrl === undefined
10
+ ? input.model
11
+ : { remote: api.createMeetingRemoteModel({ model: input.model, baseUrl: input.baseUrl, dims: input.dims }) };
12
+ return {
13
+ search: async (query, input) => {
14
+ validateMeetingSemantic(query, input);
15
+ checkCancelled(input.signal);
16
+ const api = await load();
17
+ checkCancelled(input.signal);
18
+ const selected = choice(api, input);
19
+ const embedder = await api.openMeetingEmbedder(selected, { env: options.env, signal: input.signal });
20
+ try {
21
+ return await api.readMeetingSemantic(vectors, accountId, query, embedder, {
22
+ limit: input.limit,
23
+ maxChunks: input.maxChunks,
24
+ afterChunkId: input.afterChunkId,
25
+ maxRows: input.maxRows,
26
+ maxTextBytes: input.maxTextBytes,
27
+ signal: input.signal,
28
+ });
29
+ }
30
+ finally {
31
+ await embedder.close();
32
+ }
33
+ },
34
+ generate: async (input) => {
35
+ validateMeetingEmbeddings(input);
36
+ checkCancelled(input.signal);
37
+ const api = await load();
38
+ checkCancelled(input.signal);
39
+ const selected = choice(api, input);
40
+ const descriptor = api.meetingEmbeddingModel(selected);
41
+ if (input.yes !== true)
42
+ return api.proposeMeetingEmbedding(vectors, accountId, descriptor, { signal: input.signal });
43
+ const embedder = await api.openMeetingEmbedder(selected, { env: options.env, signal: input.signal });
44
+ try {
45
+ checkCancelled(input.signal);
46
+ const rebuild = await vectors.rebuild({
47
+ accountId,
48
+ limit: input.limit,
49
+ afterTranscriptId: input.afterTranscriptId,
50
+ maxRows: input.maxRows,
51
+ maxTextBytes: input.maxTextBytes,
52
+ signal: input.signal,
53
+ });
54
+ checkCancelled(input.signal);
55
+ const result = await api.applyMeetingEmbedding(vectors, accountId, embedder, {
56
+ maxChunks: input.limit,
57
+ afterHash: input.afterHash,
58
+ maxRows: input.maxRows,
59
+ maxTextBytes: input.maxTextBytes,
60
+ signal: input.signal,
61
+ });
62
+ return { ...result, applied: true, model: descriptor, rebuild };
63
+ }
64
+ finally {
65
+ await embedder.close();
66
+ }
67
+ },
68
+ };
69
+ };
70
+ //# sourceMappingURL=meeting-semantic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meeting-semantic.js","sourceRoot":"","sources":["../src/meeting-semantic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type FileHandle } from "node:fs/promises";
2
+ /** Check the opened object before reading: Windows has no O_NOFOLLOW support. */
3
+ export declare const openOrdinaryFile: (path: string) => Promise<FileHandle>;
4
+ //# sourceMappingURL=ordinary-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ordinary-file.d.ts","sourceRoot":"","sources":["../src/ordinary-file.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAe,MAAM,kBAAkB,CAAA;AAM/D,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,SAAgB,MAAM,KAAG,OAAO,CAAC,UAAU,CA0CvE,CAAA"}
@@ -0,0 +1,51 @@
1
+ import { constants } from "node:fs";
2
+ import { lstat, open } from "node:fs/promises";
3
+ import { ZoomError } from "./errors.js";
4
+ // Node 22's Windows path stat uses a 64-bit volume serial; handle stat uses its low DWORD.
5
+ const deviceOf = (dev) => (process.platform === "win32" ? BigInt.asUintN(32, dev) : dev);
6
+ /** Check the opened object before reading: Windows has no O_NOFOLLOW support. */
7
+ export const openOrdinaryFile = async (path) => {
8
+ const before = await lstat(path, { bigint: true });
9
+ if (before.isSymbolicLink())
10
+ throw new ZoomError("validation_error", "archive path must be an ordinary file without a symlink");
11
+ if (!before.isFile())
12
+ throw new ZoomError("validation_error", "archive path must be an ordinary file");
13
+ const flags = process.platform === "win32"
14
+ ? constants.O_RDONLY
15
+ : constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0);
16
+ const file = await open(path, flags);
17
+ try {
18
+ const opened = await file.stat({ bigint: true });
19
+ const after = await lstat(path, { bigint: true });
20
+ if (!opened.isFile() || !after.isFile() || before.ino !== opened.ino || before.ino !== after.ino)
21
+ throw new ZoomError("validation_error", "archive file changed while opening");
22
+ if (process.platform === "win32" && before.dev === 0n && after.dev === 0n) {
23
+ // Older Windows path stats omit the device; compare two handles before any content read.
24
+ const witness = await open(path, flags);
25
+ try {
26
+ const identified = await witness.stat({ bigint: true });
27
+ const final = await lstat(path, { bigint: true });
28
+ if (opened.dev === 0n ||
29
+ !identified.isFile() ||
30
+ !final.isFile() ||
31
+ deviceOf(identified.dev) !== deviceOf(opened.dev) ||
32
+ identified.ino !== opened.ino ||
33
+ final.ino !== before.ino ||
34
+ (final.dev !== 0n && deviceOf(final.dev) !== deviceOf(opened.dev)))
35
+ throw new ZoomError("validation_error", "archive file changed while opening");
36
+ }
37
+ finally {
38
+ await witness.close();
39
+ }
40
+ }
41
+ else if (deviceOf(before.dev) !== deviceOf(opened.dev) || deviceOf(before.dev) !== deviceOf(after.dev)) {
42
+ throw new ZoomError("validation_error", "archive file changed while opening");
43
+ }
44
+ return file;
45
+ }
46
+ catch (error) {
47
+ await file.close();
48
+ throw error;
49
+ }
50
+ };
51
+ //# sourceMappingURL=ordinary-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ordinary-file.js","sourceRoot":"","sources":["../src/ordinary-file.ts"],"names":[],"mappings":"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"}
package/dist/program.d.ts CHANGED
@@ -1,18 +1,26 @@
1
1
  import { type SleepLike } from "@wirecat/cli-core";
2
- import { type MeetingSource, type MeetingStore } from "@wirecat/cli-meetings";
2
+ import { type MeetingSource, type MeetingStore, type MeetingTranscriptStore } from "@wirecat/cli-meetings";
3
3
  import { Command } from "commander";
4
4
  import { type ArchiveService, type ArchiveTranscriptService, type RecordingsService, type RemoteMeetingsService } from "./archive-commands.js";
5
5
  import { readDownloadedFiles } from "./files.js";
6
+ import type { MeetingContextCapabilities } from "./meeting-context.js";
7
+ import { type MeetingModelOptions, type MeetingSemanticCapabilities } from "./meeting-semantic-commands.js";
6
8
  import type { TokenManager } from "./tokens.js";
9
+ import { type UnifiedSearch } from "./unified-search.js";
7
10
  export interface StoreConnection {
8
11
  store: MeetingStore;
9
12
  accountId: number;
10
13
  close: () => Promise<void>;
14
+ appendTranscripts?: MeetingTranscriptStore["appendTranscripts"];
15
+ unifiedSearch?: UnifiedSearch;
16
+ meetingContext?: MeetingContextCapabilities;
17
+ meetingSemantic?: MeetingSemanticCapabilities;
11
18
  }
12
19
  export interface StoreConnectRequest {
13
20
  profile: string;
14
21
  externalId: string;
15
22
  intent: "read" | "ingestion";
23
+ capability?: "transcript-append";
16
24
  }
17
25
  export interface ProgramDeps {
18
26
  configPath: string;
@@ -21,6 +29,10 @@ export interface ProgramDeps {
21
29
  store?: MeetingStore;
22
30
  accountId?: number;
23
31
  connectStore?: (request: StoreConnectRequest) => Promise<StoreConnection>;
32
+ transcriptStore?: MeetingTranscriptStore;
33
+ unifiedSearch?: UnifiedSearch;
34
+ meetingContext?: MeetingContextCapabilities;
35
+ meetingSemantic?: MeetingSemanticCapabilities;
24
36
  source?: MeetingSource;
25
37
  recordings?: RecordingsService;
26
38
  remoteMeetings?: RemoteMeetingsService;
@@ -46,6 +58,9 @@ export interface ProgramDeps {
46
58
  serveMcp?: (options: {
47
59
  signal: AbortSignal;
48
60
  maxResultBytes?: number;
61
+ includeUnifiedSearch?: boolean;
62
+ includeMeetingContext?: boolean;
63
+ semanticModel?: MeetingModelOptions;
49
64
  }) => Promise<void>;
50
65
  streamData?: (text: string, signal: AbortSignal) => Promise<void>;
51
66
  }
@@ -1 +1 @@
1
- {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"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"}
package/dist/program.js CHANGED
@@ -1,20 +1,25 @@
1
1
  import { CliError, createDeadline, createRenderer, exitCodeFor, fieldsOf, GENERIC_FAILURE, projectFields, realSleep, } from "@wirecat/cli-core";
2
- import { importFiles, listed, MeetingError, pull } from "@wirecat/cli-meetings";
2
+ import { importFiles, listed, MeetingError, pull, } from "@wirecat/cli-meetings";
3
3
  import { addMeetingCommands } from "@wirecat/cli-meetings/cli";
4
4
  import { Command, CommanderError } from "commander";
5
5
  import { addZoomSkillCommands } from "./agent-skill.js";
6
6
  import { ZoomApiSource } from "./api.js";
7
7
  import { addArchiveCommands, } from "./archive-commands.js";
8
+ import { applyArchiveImport, preflightArchiveImport } from "./archive-import.js";
8
9
  import { readArchiveTranscripts, searchArchiveTranscripts } from "./archive-transcripts.js";
9
10
  import { addStandardCommands, annotateMeetingCommands } from "./commands.js";
10
11
  import { profileAccountKey, readConfig, setConfig } from "./config.js";
11
12
  import { checkCancelled, ZoomError } from "./errors.js";
12
13
  import { bytes, duration, resetCliOptions, startExecution } from "./execution.js";
13
14
  import { FilesSource, importFile, readDownloadedFiles, validateDownloadedFiles } from "./files.js";
15
+ import { addIngestionSearchCommands } from "./ingestion-search-commands.js";
14
16
  import { login } from "./login.js";
17
+ import { addMeetingContextCommands } from "./meeting-context-commands.js";
18
+ import { addMeetingSemanticCommands, validateMeetingModel, } from "./meeting-semantic-commands.js";
15
19
  import { getZoomProfile, inspectArchive, inspectArchiveLocks, recoverArchiveLocks, verifyArchive, ZoomRecordings, } from "./recordings.js";
16
20
  import { ZoomRemoteMeetings } from "./remote-meetings.js";
17
21
  import { emitReceipt } from "./streaming.js";
22
+ import { runUnifiedSearch } from "./unified-search.js";
18
23
  import { VERSION } from "./version.js";
19
24
  import { addWatchCommand } from "./watch-commands.js";
20
25
  const unavailable = async () => {
@@ -35,7 +40,7 @@ const unavailableStore = {
35
40
  cursor: unavailable,
36
41
  setCursor: unavailable,
37
42
  };
38
- const render = (value, format, deps, fields) => {
43
+ const render = (value, format, deps, fields, preserveEnvelope = false) => {
39
44
  if (fields)
40
45
  value = projectFields(value, fields);
41
46
  const chunks = [];
@@ -44,7 +49,8 @@ const render = (value, format, deps, fields) => {
44
49
  color: false,
45
50
  streams: { data: (text) => chunks.push(`${text}\n`), diagnostic: deps.diagnostic },
46
51
  });
47
- if (format === "jsonl" &&
52
+ if (!preserveEnvelope &&
53
+ format === "jsonl" &&
48
54
  typeof value === "object" &&
49
55
  value !== null &&
50
56
  "items" in value &&
@@ -143,7 +149,10 @@ export const createProgram = (deps) => {
143
149
  "serve",
144
150
  "skill",
145
151
  "watch",
146
- ].includes(family.name()))
152
+ "search",
153
+ ].includes(family.name()) ||
154
+ (family.name() === "meetings" &&
155
+ ["evidence", "context", "task-proposal", "semantic", "embeddings"].includes(action.name())))
147
156
  return;
148
157
  const config = getConfig();
149
158
  if (opts.offline && action.name() === "pull" && config.source === "api" && !deps.source)
@@ -357,7 +366,7 @@ export const createProgram = (deps) => {
357
366
  let watchSince;
358
367
  const watchSleep = deps.sleep;
359
368
  const receipt = async (value) => {
360
- const text = render(value, program.opts().jsonl ? "jsonl" : "text", deps, fields);
369
+ const text = render(value, program.opts().jsonl ? "jsonl" : program.opts().json ? "json" : "text", deps, fields);
361
370
  const operation = signal();
362
371
  const grace = operation.aborted ? createDeadline({ timeoutMs: 1000 }) : undefined;
363
372
  try {
@@ -564,13 +573,122 @@ export const createProgram = (deps) => {
564
573
  .command("serve")
565
574
  .description("serve read-only meeting tools over MCP stdio")
566
575
  .requiredOption("--mcp", "use the MCP JSON-RPC protocol")
567
- .action(async () => {
576
+ .option("--unified-search", "include selected-profile meetings-only unified search")
577
+ .option("--meeting-context", "include account-fixed evidence, person context and task proposals")
578
+ .option("--semantic", "include read-only meeting vector search with an explicit query model")
579
+ .option("--model <id>", "explicit installed query model, or remote model at --base-url")
580
+ .option("--base-url <url>", "explicit remote embedding endpoint for semantic queries")
581
+ .option("--dims <count>", "remote embedding dimensions", bytes)
582
+ .action(async (options) => {
568
583
  const opts = program.opts();
569
584
  if (opts.json || opts.jsonl || opts.fields)
570
585
  throw new ZoomError("validation_error", "MCP stdio controls its own output; omit --json, --jsonl and --fields");
571
586
  if (!deps.serveMcp)
572
587
  throw new ZoomError("configuration_error", "the MCP server adapter is not available");
573
- await deps.serveMcp({ signal: signal(), maxResultBytes: program.opts().maxOutputBytes });
588
+ if (options.semantic)
589
+ validateMeetingModel({ model: options.model ?? "", baseUrl: options.baseUrl, dims: options.dims });
590
+ else if (options.model !== undefined || options.baseUrl !== undefined || options.dims !== undefined)
591
+ throw new ZoomError("validation_error", "MCP model options require --semantic");
592
+ if (options.semantic && options.baseUrl !== undefined && opts.offline)
593
+ throw new ZoomError("configuration_error", "remote embeddings require network access; remove --offline");
594
+ await deps.serveMcp({
595
+ signal: signal(),
596
+ maxResultBytes: program.opts().maxOutputBytes,
597
+ ...(options.unifiedSearch ? { includeUnifiedSearch: true } : {}),
598
+ ...(options.meetingContext ? { includeMeetingContext: true } : {}),
599
+ ...(options.semantic
600
+ ? { semanticModel: { model: options.model ?? "", baseUrl: options.baseUrl, dims: options.dims } }
601
+ : {}),
602
+ });
603
+ });
604
+ addIngestionSearchCommands(program, {
605
+ signal,
606
+ output: (value) => buffer(render(value, program.opts().jsonl ? "jsonl" : program.opts().json ? "json" : "text", deps, fields, true)),
607
+ outputItems,
608
+ receipt,
609
+ preflight: preflightArchiveImport,
610
+ apply: async function* (plan) {
611
+ if (plan.occurrences === 0)
612
+ return;
613
+ let store = deps.transcriptStore;
614
+ let accountId = selectedAccountId;
615
+ if (!store) {
616
+ const config = getConfig();
617
+ if (!config.accountProfile || !deps.connectStore)
618
+ throw new ZoomError("configuration_error", "select a local profile with an available transcript append store");
619
+ connection = await deps.connectStore({
620
+ profile: config.accountProfile,
621
+ externalId: profileAccountKey(config.accountProfile),
622
+ intent: "ingestion",
623
+ capability: "transcript-append",
624
+ });
625
+ accountId = connection.accountId;
626
+ if (!connection.appendTranscripts)
627
+ throw new ZoomError("configuration_error", "the installed meeting store does not support transcript append");
628
+ store = { appendTranscripts: connection.appendTranscripts };
629
+ }
630
+ for await (const item of applyArchiveImport(plan, store, {
631
+ accountId: accountId ?? 0,
632
+ now: deps.now?.(),
633
+ signal: signal(),
634
+ }))
635
+ yield item;
636
+ },
637
+ search: async (request) => {
638
+ if (deps.unifiedSearch)
639
+ return runUnifiedSearch(deps.unifiedSearch, request);
640
+ const config = getConfig();
641
+ if (!config.accountProfile || !deps.connectStore)
642
+ throw new ZoomError("configuration_error", "select a stored local profile for unified search");
643
+ connection = await deps.connectStore({
644
+ profile: config.accountProfile,
645
+ externalId: profileAccountKey(config.accountProfile),
646
+ intent: "read",
647
+ });
648
+ if (!connection.unifiedSearch)
649
+ throw new ZoomError("configuration_error", "unified search is unavailable in this store connector");
650
+ return runUnifiedSearch(connection.unifiedSearch, request);
651
+ },
652
+ });
653
+ addMeetingContextCommands(program, {
654
+ signal,
655
+ output: (value) => buffer(render(value, program.opts().jsonl ? "jsonl" : program.opts().json ? "json" : "text", deps, fields, true)),
656
+ context: async () => {
657
+ if (deps.meetingContext)
658
+ return deps.meetingContext;
659
+ const config = getConfig();
660
+ if (!config.accountProfile || !deps.connectStore)
661
+ throw new ZoomError("configuration_error", "select a stored local profile for meeting context");
662
+ connection = await deps.connectStore({
663
+ profile: config.accountProfile,
664
+ externalId: profileAccountKey(config.accountProfile),
665
+ intent: "read",
666
+ });
667
+ if (!connection.meetingContext)
668
+ throw new ZoomError("configuration_error", "meeting context is unavailable in this store connector");
669
+ return connection.meetingContext;
670
+ },
671
+ });
672
+ addMeetingSemanticCommands(program, {
673
+ signal,
674
+ offline: () => Boolean(program.opts().offline),
675
+ receipt,
676
+ output: (value) => buffer(render(value, program.opts().jsonl ? "jsonl" : program.opts().json ? "json" : "text", deps, fields, true)),
677
+ capabilities: async () => {
678
+ if (deps.meetingSemantic)
679
+ return deps.meetingSemantic;
680
+ const config = getConfig();
681
+ if (!config.accountProfile || !deps.connectStore)
682
+ throw new ZoomError("configuration_error", "select a stored local profile for meeting vectors");
683
+ connection = await deps.connectStore({
684
+ profile: config.accountProfile,
685
+ externalId: profileAccountKey(config.accountProfile),
686
+ intent: "read",
687
+ });
688
+ if (!connection.meetingSemantic)
689
+ throw new ZoomError("configuration_error", "meeting vector capabilities are unavailable in this store connector");
690
+ return connection.meetingSemantic;
691
+ },
574
692
  });
575
693
  annotateMeetingCommands(program);
576
694
  const parseAsync = program.parseAsync.bind(program);
@@ -650,8 +768,19 @@ export const run = async (args, deps) => {
650
768
  ["commander.helpDisplayed", "commander.help", "commander.version"].includes(String(error.code)))
651
769
  return 0;
652
770
  const typed = error instanceof CliError || error instanceof MeetingError;
653
- const code = typed ? error.code : error instanceof CommanderError ? "validation_error" : "generic_failure";
654
- const message = typed ? error.message : "command failed; use --help for usage";
771
+ const unknownOutcome = error instanceof Error && "code" in error && error.code === "outcome_unknown";
772
+ const code = typed
773
+ ? error.code
774
+ : unknownOutcome
775
+ ? "outcome_unknown"
776
+ : error instanceof CommanderError
777
+ ? "validation_error"
778
+ : "generic_failure";
779
+ const message = typed
780
+ ? error.message
781
+ : unknownOutcome
782
+ ? "operation outcome is unknown; verify stored state before retrying"
783
+ : "command failed; use --help for usage";
655
784
  deps.diagnostic(`${JSON.stringify({ error: { code, message } })}\n`);
656
785
  return code === "generic_failure" ? GENERIC_FAILURE : exitCodeFor(code);
657
786
  }