@wirecat/cli-core 0.532.0 → 0.534.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/CHANGELOG.md +24 -0
- package/dist/background/system.js +5 -3
- package/dist/cli/messenger/search-answers.js +2 -1
- package/dist/entities/hit.d.ts +2 -0
- package/dist/entities/hit.js +2 -0
- package/dist/entities/index.d.ts +1 -0
- package/dist/mail/index.d.ts +1 -1
- package/dist/mail/index.js +1 -1
- package/dist/mail/parse.d.ts +9 -1
- package/dist/mail/parse.js +9 -2
- package/dist/meetings/store.d.ts +2 -0
- package/dist/meetings/testing/contract.js +6 -1
- package/dist/meetings/testing/memory.js +9 -0
- package/dist/services/search-all-meetings.d.ts +3 -0
- package/dist/services/search-all-meetings.js +3 -0
- package/dist/store/sqlite/meetings.js +19 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,30 @@ shape of this file.
|
|
|
7
7
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
|
+
## 0.534.0 — 01.11.2026
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`parseMail` also returns `messageId`, `references`, `replyTo` and `date`**, and takes a third argument, the most
|
|
15
|
+
attachments to keep (`MAX_ATTACHMENTS`, 50, by default), so a command that lists one message's files can ask for all
|
|
16
|
+
of them.
|
|
17
|
+
|
|
18
|
+
## 0.533.0 — 01.11.2026
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- **A `search all` meeting transcript hit names its cue and its speaker**: `cue_ref`
|
|
23
|
+
(`meeting:<account>/<meeting>/<transcript>/<cue>`) and `sender_name` (marked untrusted). `meetings passage <cue_ref>
|
|
24
|
+
--before-n 3 --after-n 3` opens the lines around it; `ref` stays the meeting. Chat and summary hits are unchanged.
|
|
25
|
+
`SearchHit` from the meetings store carries the same cue as `ref` and `speakerName`; `MeetingSearchItem` carries
|
|
26
|
+
`cueRef` and `speakerName`.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- **A `serve` unit or launchd agent survives an upgrade with pnpm.** `server install` wrote the script's resolved
|
|
31
|
+
path, a versioned folder in pnpm's global store that the next upgrade removes, so the unit could not start until it
|
|
32
|
+
was installed again. It now writes the path the shim gave, a link pnpm points at the new version.
|
|
33
|
+
|
|
10
34
|
## 0.532.0 — 01.11.2026
|
|
11
35
|
|
|
12
36
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { execFile, spawn } from "node:child_process";
|
|
2
|
-
import { closeSync, mkdirSync, openSync
|
|
3
|
-
import { dirname } from "node:path";
|
|
2
|
+
import { closeSync, mkdirSync, openSync } from "node:fs";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
4
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
5
5
|
import { CliError } from "@wirecat/cli-base";
|
|
6
6
|
export const runProgram = (argv, env) => new Promise((resolve, reject) => {
|
|
@@ -14,7 +14,9 @@ export const runProgram = (argv, env) => new Promise((resolve, reject) => {
|
|
|
14
14
|
});
|
|
15
15
|
});
|
|
16
16
|
export const thisMachine = () => {
|
|
17
|
-
|
|
17
|
+
// The path as the package manager's shim gave it, not resolved: pnpm's global link keeps its name across upgrades
|
|
18
|
+
// while the folder it points at is versioned and removed by the next upgrade, which would leave the unit dead.
|
|
19
|
+
const entry = [process.execPath, resolve(process.argv[1] ?? "")];
|
|
18
20
|
return {
|
|
19
21
|
platform: process.platform,
|
|
20
22
|
run: runProgram,
|
|
@@ -275,7 +275,7 @@ const ALL_HIT_UNTRUSTED = {
|
|
|
275
275
|
document: DOCUMENT_HIT_UNTRUSTED,
|
|
276
276
|
note: undefined,
|
|
277
277
|
event: ["title", "excerpt"],
|
|
278
|
-
meeting: ["title", "excerpt"],
|
|
278
|
+
meeting: ["title", "excerpt", "sender_name"],
|
|
279
279
|
};
|
|
280
280
|
export const allHitItem = (item) => item.kind === "meeting"
|
|
281
281
|
? {
|
|
@@ -289,6 +289,7 @@ export const allHitItem = (item) => item.kind === "meeting"
|
|
|
289
289
|
offset_ms: item.startMs,
|
|
290
290
|
scope: item.scope,
|
|
291
291
|
id: String(item.id),
|
|
292
|
+
...(item.cueRef === undefined ? {} : { cue_ref: item.cueRef, sender_name: item.speakerName ?? null }),
|
|
292
293
|
untrusted: ALL_HIT_UNTRUSTED.meeting,
|
|
293
294
|
}
|
|
294
295
|
: defined({
|
package/dist/entities/hit.d.ts
CHANGED
|
@@ -22,6 +22,8 @@ export declare const hit: v.StrictObjectSchema<{
|
|
|
22
22
|
readonly offset_ms: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>, undefined>;
|
|
23
23
|
/** A meeting passage's place: its transcript, chat or summary. */
|
|
24
24
|
readonly scope: v.OptionalSchema<v.PicklistSchema<["transcript", "chat", "summary"], undefined>, undefined>;
|
|
25
|
+
/** A meeting transcript hit's cue, which `meetings passage` opens with the lines around it. */
|
|
26
|
+
readonly cue_ref: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
25
27
|
/** A meeting passage's stored line, so two passages of one meeting stay apart; `search meetings` gives the same. */
|
|
26
28
|
readonly id: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
27
29
|
/** A message's files; absent when it has none. */
|
package/dist/entities/hit.js
CHANGED
|
@@ -24,6 +24,8 @@ export const hit = v.strictObject({
|
|
|
24
24
|
offset_ms: v.optional(v.nullable(count)),
|
|
25
25
|
/** A meeting passage's place: its transcript, chat or summary. */
|
|
26
26
|
scope: v.optional(v.picklist(["transcript", "chat", "summary"])),
|
|
27
|
+
/** A meeting transcript hit's cue, which `meetings passage` opens with the lines around it. */
|
|
28
|
+
cue_ref: v.optional(reference),
|
|
27
29
|
/** A meeting passage's stored line, so two passages of one meeting stay apart; `search meetings` gives the same. */
|
|
28
30
|
id: v.optional(v.pipe(v.string(), v.minLength(1))),
|
|
29
31
|
/** A message's files; absent when it has none. */
|
package/dist/entities/index.d.ts
CHANGED
|
@@ -4567,6 +4567,7 @@ export declare const ENTITIES: {
|
|
|
4567
4567
|
readonly found_by: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<["title", "words", "meaning"], undefined>, undefined>, undefined>;
|
|
4568
4568
|
readonly offset_ms: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>, undefined>;
|
|
4569
4569
|
readonly scope: v.OptionalSchema<v.PicklistSchema<["transcript", "chat", "summary"], undefined>, undefined>;
|
|
4570
|
+
readonly cue_ref: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>, undefined>;
|
|
4570
4571
|
readonly id: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
4571
4572
|
readonly attachments: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
4572
4573
|
readonly position: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
package/dist/mail/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export { dropMissing, type Gone, tooManyGone } from "./gone.js";
|
|
|
6
6
|
export { type AuthVerdicts, HEADER_FIELDS, headersOf, type MailHeaders, mailHeadersOf } from "./headers.js";
|
|
7
7
|
export { type MailIdsInput, mailIds } from "./ids.js";
|
|
8
8
|
export { decodedLabelName, decodeMailboxName, labelName, systemLabel } from "./labels.js";
|
|
9
|
-
export { type Address, htmlToText, looksLikeHtml, MAX_BODY_CHARS, type ParsedMail, parseMail, } from "./parse.js";
|
|
9
|
+
export { type Address, htmlToText, looksLikeHtml, MAX_ATTACHMENTS, MAX_BODY_CHARS, type ParsedMail, parseMail, } from "./parse.js";
|
|
10
10
|
export { PRESET_NAMES, PRESETS, type PresetName, presetMatches } from "./presets.js";
|
|
11
11
|
export { domainsToAge, groupKey, type Probe, type ProbeGroup, probeMail, SUGGEST_RULE } from "./probe.js";
|
|
12
12
|
export { type MailFolderProgress, mailProgress } from "./progress.js";
|
package/dist/mail/index.js
CHANGED
|
@@ -6,7 +6,7 @@ export { dropMissing, tooManyGone } from "./gone.js";
|
|
|
6
6
|
export { HEADER_FIELDS, headersOf, mailHeadersOf } from "./headers.js";
|
|
7
7
|
export { mailIds } from "./ids.js";
|
|
8
8
|
export { decodedLabelName, decodeMailboxName, labelName, systemLabel } from "./labels.js";
|
|
9
|
-
export { htmlToText, looksLikeHtml, MAX_BODY_CHARS, parseMail, } from "./parse.js";
|
|
9
|
+
export { htmlToText, looksLikeHtml, MAX_ATTACHMENTS, MAX_BODY_CHARS, parseMail, } from "./parse.js";
|
|
10
10
|
export { PRESET_NAMES, PRESETS, presetMatches } from "./presets.js";
|
|
11
11
|
export { domainsToAge, groupKey, probeMail, SUGGEST_RULE } from "./probe.js";
|
|
12
12
|
export { mailProgress } from "./progress.js";
|
package/dist/mail/parse.d.ts
CHANGED
|
@@ -8,6 +8,12 @@ export interface ParsedMail {
|
|
|
8
8
|
to: Address[];
|
|
9
9
|
cc: Address[];
|
|
10
10
|
bcc: Address[];
|
|
11
|
+
replyTo: Address[];
|
|
12
|
+
date: string | null;
|
|
13
|
+
/** Message-ID as the first `<id>` the header holds, brackets kept; the header as written when it holds none. */
|
|
14
|
+
messageId: string | null;
|
|
15
|
+
/** Every `<id>` of References, in the header's order, brackets kept. */
|
|
16
|
+
references: string[];
|
|
11
17
|
attachments: {
|
|
12
18
|
id: number;
|
|
13
19
|
name: string;
|
|
@@ -17,8 +23,10 @@ export interface ParsedMail {
|
|
|
17
23
|
text: string;
|
|
18
24
|
}
|
|
19
25
|
export declare const MAX_BODY_CHARS = 1000000;
|
|
26
|
+
/** What sync stores; a command that shows the files of one message passes its own limit. */
|
|
27
|
+
export declare const MAX_ATTACHMENTS = 50;
|
|
20
28
|
export declare const htmlToText: (html: string) => string;
|
|
21
29
|
/** Some senders put their HTML in the text/plain part; its first tag gives it away. */
|
|
22
30
|
export declare const looksLikeHtml: (text: string) => boolean;
|
|
23
31
|
/** A raw RFC 5322 message, as IMAP's `BODY[]` holds it. */
|
|
24
|
-
export declare const parseMail: (raw: Uint8Array, maxBodyChars?: number) => Promise<ParsedMail>;
|
|
32
|
+
export declare const parseMail: (raw: Uint8Array, maxBodyChars?: number, maxAttachments?: number) => Promise<ParsedMail>;
|
package/dist/mail/parse.js
CHANGED
|
@@ -2,6 +2,9 @@ import { CliError } from "@wirecat/cli-base";
|
|
|
2
2
|
import PostalMime, {} from "postal-mime";
|
|
3
3
|
// The store cuts a body into pieces itself; this only guards against a pathological one, like a pasted log.
|
|
4
4
|
export const MAX_BODY_CHARS = 1_000_000;
|
|
5
|
+
/** What sync stores; a command that shows the files of one message passes its own limit. */
|
|
6
|
+
export const MAX_ATTACHMENTS = 50;
|
|
7
|
+
const BRACKETED_ID = /<[^<>\s]+>/g;
|
|
5
8
|
const addresses = (list) => list
|
|
6
9
|
.flatMap((entry) => entry.group ?? [entry])
|
|
7
10
|
.flatMap(({ address, name }) => (address ? [{ email: address.toLowerCase(), name: name || null }] : []));
|
|
@@ -52,7 +55,7 @@ const bytesOf = (content) => typeof content === "string"
|
|
|
52
55
|
? content
|
|
53
56
|
: new Uint8Array(content);
|
|
54
57
|
/** A raw RFC 5322 message, as IMAP's `BODY[]` holds it. */
|
|
55
|
-
export const parseMail = async (raw, maxBodyChars = MAX_BODY_CHARS) => {
|
|
58
|
+
export const parseMail = async (raw, maxBodyChars = MAX_BODY_CHARS, maxAttachments = MAX_ATTACHMENTS) => {
|
|
56
59
|
let email;
|
|
57
60
|
try {
|
|
58
61
|
email = await PostalMime.parse(raw);
|
|
@@ -68,7 +71,11 @@ export const parseMail = async (raw, maxBodyChars = MAX_BODY_CHARS) => {
|
|
|
68
71
|
to: addresses(email.to ?? []),
|
|
69
72
|
cc: addresses(email.cc ?? []),
|
|
70
73
|
bcc: addresses(email.bcc ?? []),
|
|
71
|
-
|
|
74
|
+
replyTo: addresses(email.replyTo ?? []),
|
|
75
|
+
date: email.date ?? null,
|
|
76
|
+
messageId: email.messageId?.match(BRACKETED_ID)?.[0] ?? email.messageId ?? null,
|
|
77
|
+
references: email.references?.match(BRACKETED_ID) ?? [],
|
|
78
|
+
attachments: email.attachments.slice(0, maxAttachments).map((part, id) => ({
|
|
72
79
|
id,
|
|
73
80
|
name: (part.filename ?? `attachment-${id}`).slice(0, 200),
|
|
74
81
|
mime: part.mimeType || null,
|
package/dist/meetings/store.d.ts
CHANGED
|
@@ -88,6 +88,8 @@ export interface SearchHit {
|
|
|
88
88
|
id: number;
|
|
89
89
|
text: string;
|
|
90
90
|
startMs: number | null;
|
|
91
|
+
/** Who spoke a transcript hit's cue, as the transcript names them; absent for chat and summary hits. */
|
|
92
|
+
speakerName?: string | null;
|
|
91
93
|
/** `corrected` when a query word matched only as a stored word recognition may have garbled. */
|
|
92
94
|
match?: "words" | "corrected";
|
|
93
95
|
/** For a `corrected` hit, the stored words each such query word matched in this passage. */
|
|
@@ -62,7 +62,12 @@ export const meetingStoreContract = (make) => {
|
|
|
62
62
|
assert.equal((await s.participants("example.com", 1)).length, 1);
|
|
63
63
|
assert.equal((await s.participants("alice", 2)).length, 0);
|
|
64
64
|
assert.deepEqual((await s.search("EXAMPLE")).map((h) => h.scope).sort(), ["chat", "summary", "transcript"]);
|
|
65
|
-
|
|
65
|
+
const [ship] = await s.search("Ship");
|
|
66
|
+
assert.equal(ship?.startMs, 0);
|
|
67
|
+
const cue = t.rows.find((row) => row.id === ship?.id);
|
|
68
|
+
assert.ok(cue);
|
|
69
|
+
assert.equal(ship?.ref, `meeting:${d.meeting.accountId}/${d.meeting.id}/${t.transcript.id}/${cue.position}`, "a transcript hit names its cue");
|
|
70
|
+
assert.equal(ship?.speakerName, cue.speakerName);
|
|
66
71
|
}),
|
|
67
72
|
test("idempotence, updates and omitted parts retain history", async (s) => {
|
|
68
73
|
const input = sampleMeeting();
|
|
@@ -3,6 +3,7 @@ import { EVENT_QUERY } from "../event-query.js";
|
|
|
3
3
|
import { MEETING_QUERY, meetingItem } from "../item.js";
|
|
4
4
|
import { eventItem } from "../read-answers.js";
|
|
5
5
|
import { MeetingError, positiveInteger } from "../reads.js";
|
|
6
|
+
import { formatMeetingReference } from "../reference.js";
|
|
6
7
|
const overlap = (start, end, from, to) => start !== null && start <= to && (end ?? start) >= from;
|
|
7
8
|
/** A test store keeps no accounts: every id is an account of the `memory` provider. */
|
|
8
9
|
const MEMORY_OWNER = (id) => ({ provider: "memory", account: String(id) });
|
|
@@ -107,11 +108,19 @@ export const memoryMeetingStore = () => {
|
|
|
107
108
|
const rows = d.transcripts
|
|
108
109
|
.filter((t) => t.transcript.supersededAt === null && t.transcript.deletedAt === null)
|
|
109
110
|
.flatMap((t) => t.rows.map((r) => ({
|
|
111
|
+
ref: formatMeetingReference({
|
|
112
|
+
type: "meeting",
|
|
113
|
+
accountId: d.meeting.accountId,
|
|
114
|
+
meetingId: d.meeting.id,
|
|
115
|
+
transcriptId: t.transcript.id,
|
|
116
|
+
cuePosition: r.position,
|
|
117
|
+
}),
|
|
110
118
|
meetingId: d.meeting.id,
|
|
111
119
|
scope: "transcript",
|
|
112
120
|
id: r.id,
|
|
113
121
|
text: r.text,
|
|
114
122
|
startMs: r.startMs,
|
|
123
|
+
speakerName: r.speakerName,
|
|
115
124
|
})));
|
|
116
125
|
rows.push(...d.chat.map((r) => ({
|
|
117
126
|
meetingId: d.meeting.id,
|
|
@@ -19,6 +19,9 @@ export interface MeetingSearchItem {
|
|
|
19
19
|
scope: SearchHit["scope"];
|
|
20
20
|
id: number;
|
|
21
21
|
startMs: number | null;
|
|
22
|
+
/** A transcript hit's cue, `meeting:<account>/<meeting>/<transcript>/<cue>`, which `meetings passage` opens. */
|
|
23
|
+
cueRef?: string;
|
|
24
|
+
speakerName?: string | null;
|
|
22
25
|
}
|
|
23
26
|
export interface MeetingSearchCursor {
|
|
24
27
|
accountId: number;
|
|
@@ -104,6 +104,9 @@ const collectMeetings = async (store, account, request, query) => {
|
|
|
104
104
|
scope: hit.scope,
|
|
105
105
|
id: hit.id,
|
|
106
106
|
startMs: hit.startMs,
|
|
107
|
+
...(hit.scope === "transcript" && hit.ref !== undefined
|
|
108
|
+
? { cueRef: hit.ref, speakerName: hit.speakerName ?? null }
|
|
109
|
+
: {}),
|
|
107
110
|
},
|
|
108
111
|
});
|
|
109
112
|
if (collected.items.length > request.limit) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CliError } from "@wirecat/cli-base";
|
|
2
|
-
import { joinKeyOf, MeetingError } from "../../meetings/index.js";
|
|
2
|
+
import { formatMeetingReference, joinKeyOf, MeetingError } from "../../meetings/index.js";
|
|
3
3
|
import { normalize } from "../normalize.js";
|
|
4
4
|
import * as eventQueries from "./events.js";
|
|
5
5
|
import { fromJson, int, page, str, toJson } from "./events.js";
|
|
@@ -515,17 +515,18 @@ const search = (database, query, filter) => {
|
|
|
515
515
|
const rows = database
|
|
516
516
|
.prepare(`WITH hit AS (SELECT rowid AS r FROM meeting_words WHERE meeting_words MATCH ?),
|
|
517
517
|
picked AS (SELECT id, row_number() OVER (ORDER BY coalesce(started_at, 0) DESC, id) AS n FROM (${picked.sql}))
|
|
518
|
-
SELECT p.n, 0 AS kind, t.id AS a, r.position AS b, r.id, t.meeting_id, r.start_ms, coalesce(length(CAST(r.text AS BLOB)),0) AS bytes
|
|
518
|
+
SELECT p.n, 0 AS kind, t.id AS a, r.position AS b, r.id, t.meeting_id, r.start_ms, coalesce(length(CAST(r.text AS BLOB)),0) AS bytes,
|
|
519
|
+
r.speaker_name AS speaker, m.account_id
|
|
519
520
|
FROM hit h JOIN meeting_transcript_rows r ON h.r % 4 = 1 AND r.id = h.r / 4
|
|
520
521
|
JOIN meeting_transcripts t ON t.id = r.meeting_transcript_id
|
|
521
522
|
AND t.superseded_at IS NULL AND t.deleted_at IS NULL
|
|
522
|
-
JOIN picked p ON p.id = t.meeting_id
|
|
523
|
+
JOIN picked p ON p.id = t.meeting_id JOIN meetings m ON m.id = t.meeting_id
|
|
523
524
|
UNION ALL
|
|
524
|
-
SELECT p.n, 1, c.id, 0, c.id, c.meeting_id, NULL, coalesce(length(CAST(c.text AS BLOB)),0)
|
|
525
|
+
SELECT p.n, 1, c.id, 0, c.id, c.meeting_id, NULL, coalesce(length(CAST(c.text AS BLOB)),0), NULL, NULL
|
|
525
526
|
FROM hit h JOIN meeting_chat_messages c ON h.r % 4 = 2 AND c.id = h.r / 4
|
|
526
527
|
JOIN picked p ON p.id = c.meeting_id
|
|
527
528
|
UNION ALL
|
|
528
|
-
SELECT p.n, 2, s.id, 0, s.id, s.meeting_id, NULL, coalesce(length(CAST(s.title AS BLOB)),0)+coalesce(length(CAST(s.overview AS BLOB)),0)+coalesce(length(CAST(s.sections AS BLOB)),0)+coalesce(length(CAST(s.next_steps AS BLOB)),0)+coalesce(length(CAST(s.content AS BLOB)),0)
|
|
529
|
+
SELECT p.n, 2, s.id, 0, s.id, s.meeting_id, NULL, coalesce(length(CAST(s.title AS BLOB)),0)+coalesce(length(CAST(s.overview AS BLOB)),0)+coalesce(length(CAST(s.sections AS BLOB)),0)+coalesce(length(CAST(s.next_steps AS BLOB)),0)+coalesce(length(CAST(s.content AS BLOB)),0), NULL, NULL
|
|
529
530
|
FROM hit h JOIN meeting_summaries s ON h.r % 4 = 3 AND s.id = h.r / 4
|
|
530
531
|
JOIN picked p ON p.id = s.meeting_id
|
|
531
532
|
ORDER BY 1, 2, 3, 4 LIMIT 10001`)
|
|
@@ -540,7 +541,20 @@ const search = (database, query, filter) => {
|
|
|
540
541
|
const scopes = ["transcript", "chat", "summary"];
|
|
541
542
|
return rows.map((row) => {
|
|
542
543
|
const scope = scopes[Number(row.kind)];
|
|
544
|
+
const cue = scope === "transcript"
|
|
545
|
+
? {
|
|
546
|
+
ref: formatMeetingReference({
|
|
547
|
+
type: "meeting",
|
|
548
|
+
accountId: Number(row.account_id),
|
|
549
|
+
meetingId: Number(row.meeting_id),
|
|
550
|
+
transcriptId: Number(row.a),
|
|
551
|
+
cuePosition: Number(row.b),
|
|
552
|
+
}),
|
|
553
|
+
speakerName: row.speaker === null ? null : String(row.speaker),
|
|
554
|
+
}
|
|
555
|
+
: {};
|
|
543
556
|
return {
|
|
557
|
+
...cue,
|
|
544
558
|
meetingId: Number(row.meeting_id),
|
|
545
559
|
scope,
|
|
546
560
|
id: Number(row.id),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wirecat/cli-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.534.0",
|
|
4
4
|
"description": "The messenger-neutral half of a messaging CLI: domain model, message locators, rendering, name resolution, the SQLite seam, the command skeleton and shared read commands, the send guard, run records and the message store",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Viacheslav Ptsarev",
|