@wirecat/bitrix24-cli 0.0.0-stage → 0.1.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 +31 -0
- package/LICENSE +204 -0
- package/README.md +17 -2
- package/dist/api-keys.d.ts +21 -0
- package/dist/api-keys.d.ts.map +1 -0
- package/dist/api-keys.js +58 -0
- package/dist/api-keys.js.map +1 -0
- package/dist/bin/b24.d.ts +3 -0
- package/dist/bin/b24.d.ts.map +1 -0
- package/dist/bin/b24.js +40 -0
- package/dist/bin/b24.js.map +1 -0
- package/dist/bitrix/errors.d.ts +22 -0
- package/dist/bitrix/errors.d.ts.map +1 -0
- package/dist/bitrix/errors.js +76 -0
- package/dist/bitrix/errors.js.map +1 -0
- package/dist/bitrix/methods.d.ts +13 -0
- package/dist/bitrix/methods.d.ts.map +1 -0
- package/dist/bitrix/methods.js +33 -0
- package/dist/bitrix/methods.js.map +1 -0
- package/dist/bitrix/transport.d.ts +50 -0
- package/dist/bitrix/transport.d.ts.map +1 -0
- package/dist/bitrix/transport.js +189 -0
- package/dist/bitrix/transport.js.map +1 -0
- package/dist/bitrix/webhook.d.ts +14 -0
- package/dist/bitrix/webhook.d.ts.map +1 -0
- package/dist/bitrix/webhook.js +29 -0
- package/dist/bitrix/webhook.js.map +1 -0
- package/dist/bundle/all-profiles-QJ444GSX.js +24 -0
- package/dist/bundle/anthropic-RHRAVHC2.js +70 -0
- package/dist/bundle/app-server-QIT6S7AZ.js +224 -0
- package/dist/bundle/b24.js +32 -0
- package/dist/bundle/bun-H6RSODZ3.js +169 -0
- package/dist/bundle/bun-sqlite-BO4LTQHX.js +69 -0
- package/dist/bundle/chunk-2KCZ7BKW.js +215 -0
- package/dist/bundle/chunk-2SNUMZ7S.js +1028 -0
- package/dist/bundle/chunk-45AKJVKV.js +24 -0
- package/dist/bundle/chunk-4PDYYS5K.js +2 -0
- package/dist/bundle/chunk-5D4AEUVA.js +24783 -0
- package/dist/bundle/chunk-6WY72XVQ.js +216 -0
- package/dist/bundle/chunk-7GRZAKBB.js +639 -0
- package/dist/bundle/chunk-ADLS6FVG.js +24600 -0
- package/dist/bundle/chunk-BCF7P4FZ.js +558 -0
- package/dist/bundle/chunk-CNNEA2M4.js +54 -0
- package/dist/bundle/chunk-CXL33BFL.js +570 -0
- package/dist/bundle/chunk-CZ23EVP4.js +1691 -0
- package/dist/bundle/chunk-D5S6QV6R.js +95 -0
- package/dist/bundle/chunk-DFDN6AUB.js +21 -0
- package/dist/bundle/chunk-DTXERR44.js +35 -0
- package/dist/bundle/chunk-EVYSBZ3I.js +153 -0
- package/dist/bundle/chunk-EXOOKUEA.js +82 -0
- package/dist/bundle/chunk-FLUEXJ4X.js +53 -0
- package/dist/bundle/chunk-FOTREPNS.js +366 -0
- package/dist/bundle/chunk-FZL7F5NR.js +2022 -0
- package/dist/bundle/chunk-H2ADPPSH.js +50910 -0
- package/dist/bundle/chunk-HAXNUIGQ.js +1245 -0
- package/dist/bundle/chunk-HGL63O5V.js +288 -0
- package/dist/bundle/chunk-INFYLWUA.js +929 -0
- package/dist/bundle/chunk-IRV2PCQ2.js +5213 -0
- package/dist/bundle/chunk-K3UIB6ZF.js +45 -0
- package/dist/bundle/chunk-LRGYKOCP.js +91 -0
- package/dist/bundle/chunk-LSPIOT6Z.js +459 -0
- package/dist/bundle/chunk-MBDK4YXG.js +34 -0
- package/dist/bundle/chunk-N6FLBXZS.js +73 -0
- package/dist/bundle/chunk-OTD2ZRXD.js +161 -0
- package/dist/bundle/chunk-P33NDCDI.js +78 -0
- package/dist/bundle/chunk-P364PLIK.js +257 -0
- package/dist/bundle/chunk-PH5FZX6E.js +193 -0
- package/dist/bundle/chunk-POC3V3AO.js +36616 -0
- package/dist/bundle/chunk-QC53QBNC.js +143 -0
- package/dist/bundle/chunk-QGMDQ2PM.js +122 -0
- package/dist/bundle/chunk-QIPTIUMJ.js +281 -0
- package/dist/bundle/chunk-QMPN6WKD.js +3512 -0
- package/dist/bundle/chunk-QQXH2OPB.js +594 -0
- package/dist/bundle/chunk-QSNROIJL.js +413 -0
- package/dist/bundle/chunk-RRJNNPR4.js +76 -0
- package/dist/bundle/chunk-SFRNX2TI.js +6848 -0
- package/dist/bundle/chunk-SGRYYE4X.js +266 -0
- package/dist/bundle/chunk-TE3FR6MI.js +884 -0
- package/dist/bundle/chunk-U5ACMCAQ.js +12049 -0
- package/dist/bundle/chunk-VEWWAGTD.js +2315 -0
- package/dist/bundle/chunk-VL6SPMZV.js +194 -0
- package/dist/bundle/chunk-WII44RXN.js +58 -0
- package/dist/bundle/chunk-WKRQ44EH.js +528 -0
- package/dist/bundle/chunk-WTPMJYMD.js +8308 -0
- package/dist/bundle/chunk-XD4FRDSL.js +565 -0
- package/dist/bundle/chunk-XJXONOB5.js +63 -0
- package/dist/bundle/chunk-XNHSPHUN.js +48 -0
- package/dist/bundle/chunk-XRFJWHY5.js +131 -0
- package/dist/bundle/chunk-Y5E2WNWB.js +35 -0
- package/dist/bundle/chunk-YYO7D2MO.js +783 -0
- package/dist/bundle/chunk-YZ5LHE5Q.js +31 -0
- package/dist/bundle/chunk-ZDQQCXFG.js +392 -0
- package/dist/bundle/chunk-ZEW4P6AH.js +158 -0
- package/dist/bundle/chunk-ZGZT5S6B.js +3480 -0
- package/dist/bundle/chunk-ZIAQPTUS.js +82 -0
- package/dist/bundle/chunk-ZVVMGPBJ.js +50 -0
- package/dist/bundle/command-contract-OKQOE6G4.js +30 -0
- package/dist/bundle/decode-5ZPLTYV6.js +160 -0
- package/dist/bundle/dist-PII6Z6X3.js +7577 -0
- package/dist/bundle/echarts-J6LAPIX7.js +42501 -0
- package/dist/bundle/embed-YG5LDHME.js +35 -0
- package/dist/bundle/embedder-7FNUA5OZ.js +108 -0
- package/dist/bundle/first-run-JPZNWIJN.js +23 -0
- package/dist/bundle/first-screen-VQM4MTS7.js +28 -0
- package/dist/bundle/instructions-AXWTQHMR.js +11 -0
- package/dist/bundle/mcp-7F46P6AM.js +165 -0
- package/dist/bundle/mcp-J5R5A65I.js +87 -0
- package/dist/bundle/mcp-WALJM6QX.js +160 -0
- package/dist/bundle/node-CWKAIOEM.js +176 -0
- package/dist/bundle/node-P4E63KXA.js +2340 -0
- package/dist/bundle/node-TLZSIHIJ.js +21 -0
- package/dist/bundle/node-sqlite-LSEKVRDA.js +67 -0
- package/dist/bundle/oauth-THYNLRLD.js +17 -0
- package/dist/bundle/open-E47QYKFC.js +20 -0
- package/dist/bundle/openai-EWSGC3BC.js +227 -0
- package/dist/bundle/process-WKTEA3WE.js +91 -0
- package/dist/bundle/program-GO3RVP2H.js +20847 -0
- package/dist/bundle/prompt-CAQ7QR3U.js +12 -0
- package/dist/bundle/recognize-6KGHNZC3.js +23 -0
- package/dist/bundle/remote-3UO2WDC3.js +26 -0
- package/dist/bundle/rerank-2JVDPZBX.js +49 -0
- package/dist/bundle/serve-ES7AG5IK.js +19 -0
- package/dist/bundle/server-5LE5LNUQ.js +45 -0
- package/dist/bundle/server-BU4VBM6S.js +58 -0
- package/dist/bundle/state-7NH5G4XJ.js +33 -0
- package/dist/bundle/store-7O4JQD2Z.js +127 -0
- package/dist/bundle/store-maintenance-command-UDVGEY2D.js +47 -0
- package/dist/commands/api.d.ts +3 -0
- package/dist/commands/api.d.ts.map +1 -0
- package/dist/commands/api.js +130 -0
- package/dist/commands/api.js.map +1 -0
- package/dist/commands/crm-writes.d.ts +4 -0
- package/dist/commands/crm-writes.d.ts.map +1 -0
- package/dist/commands/crm-writes.js +182 -0
- package/dist/commands/crm-writes.js.map +1 -0
- package/dist/commands/crm.d.ts +3 -0
- package/dist/commands/crm.d.ts.map +1 -0
- package/dist/commands/crm.js +142 -0
- package/dist/commands/crm.js.map +1 -0
- package/dist/commands/doctor.d.ts +77 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +74 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/mcp.d.ts +3 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +97 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/session.d.ts +3 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +101 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/write.d.ts +21 -0
- package/dist/commands/write.d.ts.map +1 -0
- package/dist/commands/write.js +47 -0
- package/dist/commands/write.js.map +1 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -0
- package/dist/crm/conditions.d.ts +25 -0
- package/dist/crm/conditions.d.ts.map +1 -0
- package/dist/crm/conditions.js +78 -0
- package/dist/crm/conditions.js.map +1 -0
- package/dist/crm/deal.d.ts +27 -0
- package/dist/crm/deal.d.ts.map +1 -0
- package/dist/crm/deal.js +76 -0
- package/dist/crm/deal.js.map +1 -0
- package/dist/crm/items.d.ts +30 -0
- package/dist/crm/items.d.ts.map +1 -0
- package/dist/crm/items.js +76 -0
- package/dist/crm/items.js.map +1 -0
- package/dist/crm/lead.d.ts +36 -0
- package/dist/crm/lead.d.ts.map +1 -0
- package/dist/crm/lead.js +86 -0
- package/dist/crm/lead.js.map +1 -0
- package/dist/crm/organization.d.ts +32 -0
- package/dist/crm/organization.d.ts.map +1 -0
- package/dist/crm/organization.js +68 -0
- package/dist/crm/organization.js.map +1 -0
- package/dist/crm/person.d.ts +31 -0
- package/dist/crm/person.d.ts.map +1 -0
- package/dist/crm/person.js +68 -0
- package/dist/crm/person.js.map +1 -0
- package/dist/crm/pipeline.d.ts +17 -0
- package/dist/crm/pipeline.d.ts.map +1 -0
- package/dist/crm/pipeline.js +42 -0
- package/dist/crm/pipeline.js.map +1 -0
- package/dist/crm/product.d.ts +43 -0
- package/dist/crm/product.d.ts.map +1 -0
- package/dist/crm/product.js +42 -0
- package/dist/crm/product.js.map +1 -0
- package/dist/crm/stage.d.ts +20 -0
- package/dist/crm/stage.d.ts.map +1 -0
- package/dist/crm/stage.js +65 -0
- package/dist/crm/stage.js.map +1 -0
- package/dist/crm/user.d.ts +39 -0
- package/dist/crm/user.d.ts.map +1 -0
- package/dist/crm/user.js +54 -0
- package/dist/crm/user.js.map +1 -0
- package/dist/crm/values.d.ts +30 -0
- package/dist/crm/values.d.ts.map +1 -0
- package/dist/crm/values.js +50 -0
- package/dist/crm/values.js.map +1 -0
- package/dist/crm/walk.d.ts +19 -0
- package/dist/crm/walk.d.ts.map +1 -0
- package/dist/crm/walk.js +22 -0
- package/dist/crm/walk.js.map +1 -0
- package/dist/identity.d.ts +5 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +18 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp.d.ts +29 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +99 -0
- package/dist/mcp.js.map +1 -0
- package/dist/portal.d.ts +33 -0
- package/dist/portal.d.ts.map +1 -0
- package/dist/portal.js +46 -0
- package/dist/portal.js.map +1 -0
- package/dist/program.d.ts +6 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +45 -0
- package/dist/program.js.map +1 -0
- package/dist/reasons.d.ts +10 -0
- package/dist/reasons.d.ts.map +1 -0
- package/dist/reasons.js +28 -0
- package/dist/reasons.js.map +1 -0
- package/dist/token.d.ts +12 -0
- package/dist/token.d.ts.map +1 -0
- package/dist/token.js +41 -0
- package/dist/token.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/dist/whoami.d.ts +8 -0
- package/dist/whoami.d.ts.map +1 -0
- package/dist/whoami.js +9 -0
- package/dist/whoami.js.map +1 -0
- package/package.json +83 -4
- package/skills/bitrix24-cli/SKILL.md +41 -0
|
@@ -0,0 +1,3480 @@
|
|
|
1
|
+
import { createRequire as __bundleRequire } from "node:module";
|
|
2
|
+
const require = __bundleRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
CliError,
|
|
5
|
+
RegistryError,
|
|
6
|
+
SNAKE_CASE,
|
|
7
|
+
STEPS,
|
|
8
|
+
array,
|
|
9
|
+
boolean,
|
|
10
|
+
defineReasons,
|
|
11
|
+
defineSteps,
|
|
12
|
+
duplicates,
|
|
13
|
+
integer,
|
|
14
|
+
isCliError,
|
|
15
|
+
isoTime,
|
|
16
|
+
lazy,
|
|
17
|
+
literal,
|
|
18
|
+
maxValue,
|
|
19
|
+
minLength,
|
|
20
|
+
minValue,
|
|
21
|
+
nullable,
|
|
22
|
+
number,
|
|
23
|
+
object,
|
|
24
|
+
optional,
|
|
25
|
+
pageSchema,
|
|
26
|
+
picklist,
|
|
27
|
+
pipe,
|
|
28
|
+
reference,
|
|
29
|
+
safeParse,
|
|
30
|
+
singleLine,
|
|
31
|
+
stepOf,
|
|
32
|
+
strictObject,
|
|
33
|
+
string,
|
|
34
|
+
union,
|
|
35
|
+
variant,
|
|
36
|
+
visibleControls
|
|
37
|
+
} from "./chunk-IRV2PCQ2.js";
|
|
38
|
+
import {
|
|
39
|
+
__name
|
|
40
|
+
} from "./chunk-ZVVMGPBJ.js";
|
|
41
|
+
|
|
42
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/domain/money.js
|
|
43
|
+
var CURRENCY_SCALES = {
|
|
44
|
+
AED: 2,
|
|
45
|
+
AMD: 2,
|
|
46
|
+
AUD: 2,
|
|
47
|
+
BHD: 3,
|
|
48
|
+
BYN: 2,
|
|
49
|
+
CAD: 2,
|
|
50
|
+
CHF: 2,
|
|
51
|
+
CLP: 0,
|
|
52
|
+
CNY: 2,
|
|
53
|
+
CZK: 2,
|
|
54
|
+
DKK: 2,
|
|
55
|
+
EUR: 2,
|
|
56
|
+
GBP: 2,
|
|
57
|
+
GEL: 2,
|
|
58
|
+
HUF: 2,
|
|
59
|
+
ILS: 2,
|
|
60
|
+
INR: 2,
|
|
61
|
+
ISK: 0,
|
|
62
|
+
JPY: 0,
|
|
63
|
+
KGS: 2,
|
|
64
|
+
KRW: 0,
|
|
65
|
+
KWD: 3,
|
|
66
|
+
KZT: 2,
|
|
67
|
+
NOK: 2,
|
|
68
|
+
PLN: 2,
|
|
69
|
+
RSD: 2,
|
|
70
|
+
RUB: 2,
|
|
71
|
+
SEK: 2,
|
|
72
|
+
THB: 2,
|
|
73
|
+
TRY: 2,
|
|
74
|
+
UAH: 2,
|
|
75
|
+
USD: 2,
|
|
76
|
+
UZS: 2,
|
|
77
|
+
VND: 0
|
|
78
|
+
};
|
|
79
|
+
var refuse = /* @__PURE__ */ __name((message, reason) => {
|
|
80
|
+
throw new CliError("validation_error", message, { reason });
|
|
81
|
+
}, "refuse");
|
|
82
|
+
var DECIMAL = /^(\d{1,15})(?:\.(\d+))?$/;
|
|
83
|
+
var parseDecimal = /* @__PURE__ */ __name((text5, scale) => {
|
|
84
|
+
const match = DECIMAL.exec(text5.trim());
|
|
85
|
+
if (!match || (match[2] ?? "").length > scale)
|
|
86
|
+
return void 0;
|
|
87
|
+
return BigInt(`${match[1]}${(match[2] ?? "").padEnd(scale, "0")}`);
|
|
88
|
+
}, "parseDecimal");
|
|
89
|
+
var formatDecimal = /* @__PURE__ */ __name((units, scale) => {
|
|
90
|
+
const digits = BigInt(units).toString().padStart(scale + 1, "0");
|
|
91
|
+
return scale === 0 ? digits : `${digits.slice(0, -scale)}.${digits.slice(-scale)}`;
|
|
92
|
+
}, "formatDecimal");
|
|
93
|
+
var groupDigits = /* @__PURE__ */ __name((decimal) => {
|
|
94
|
+
const [whole = "0", fraction] = decimal.split(".");
|
|
95
|
+
const grouped2 = whole.replace(/\B(?=(\d{3})+(?!\d))/g, " ");
|
|
96
|
+
return fraction === void 0 ? grouped2 : `${grouped2}.${fraction}`;
|
|
97
|
+
}, "groupDigits");
|
|
98
|
+
var currencyOf = /* @__PURE__ */ __name((text5) => {
|
|
99
|
+
const code = typeof text5 === "string" ? text5.trim().toUpperCase() : "";
|
|
100
|
+
if (CURRENCY_SCALES[code] === void 0)
|
|
101
|
+
return refuse(`${typeof text5 === "string" && text5.trim() ? text5.trim() : "an empty currency"} is not a currency the store keeps; use one of ${Object.keys(CURRENCY_SCALES).join(", ")}`, "money.currency");
|
|
102
|
+
return code;
|
|
103
|
+
}, "currencyOf");
|
|
104
|
+
var scaleOf = /* @__PURE__ */ __name((currency) => CURRENCY_SCALES[currencyOf(currency)], "scaleOf");
|
|
105
|
+
var minorUnits = /* @__PURE__ */ __name((amount, currency, what = "an amount") => {
|
|
106
|
+
const scale = scaleOf(currency);
|
|
107
|
+
const units = typeof amount === "string" ? parseDecimal(amount, scale) : void 0;
|
|
108
|
+
if (units === void 0 || units > BigInt(Number.MAX_SAFE_INTEGER))
|
|
109
|
+
return refuse(`${what} is a decimal string with at most ${scale} decimal${scale === 1 ? "" : "s"} for ${currency}, such as "${formatDecimal(5e3 * 10 ** scale, scale)}"`, "money.amount");
|
|
110
|
+
return Number(units);
|
|
111
|
+
}, "minorUnits");
|
|
112
|
+
var moneyOf = /* @__PURE__ */ __name((units, currency) => ({
|
|
113
|
+
amount: formatDecimal(units, scaleOf(currency)),
|
|
114
|
+
currency
|
|
115
|
+
}), "moneyOf");
|
|
116
|
+
var moneyLabel = /* @__PURE__ */ __name((units, currency) => `${groupDigits(formatDecimal(units, scaleOf(currency)))} ${currency}`, "moneyLabel");
|
|
117
|
+
var QUANTITY_SCALE = 3;
|
|
118
|
+
var quantityOf = /* @__PURE__ */ __name((text5) => {
|
|
119
|
+
const thousandths = typeof text5 === "string" ? parseDecimal(text5, QUANTITY_SCALE) : void 0;
|
|
120
|
+
if (thousandths === void 0 || thousandths === 0n)
|
|
121
|
+
return refuse('a quantity is a decimal string above 0 with at most 3 decimals, such as "1.5"', "money.quantity");
|
|
122
|
+
const plain = formatDecimal(thousandths, QUANTITY_SCALE).replace(/\.?0+$/, "");
|
|
123
|
+
return { text: plain, thousandths };
|
|
124
|
+
}, "quantityOf");
|
|
125
|
+
var lineUnits = /* @__PURE__ */ __name((thousandths, unitPrice) => Number((thousandths * BigInt(unitPrice) + 500n) / 1000n), "lineUnits");
|
|
126
|
+
|
|
127
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/domain/finance.js
|
|
128
|
+
var INVOICE_DIRECTIONS = ["receivable", "payable"];
|
|
129
|
+
var INVOICE_STATUSES = ["draft", "issued", "partly_paid", "paid", "void"];
|
|
130
|
+
var MONEY_DIRECTIONS = ["in", "out"];
|
|
131
|
+
var FINANCE_REVIEWS = ["proposed", "confirmed", "rejected"];
|
|
132
|
+
var settledStatus = /* @__PURE__ */ __name((current, total, paid) => {
|
|
133
|
+
if (current === "draft" || current === "void")
|
|
134
|
+
return current;
|
|
135
|
+
if (paid <= 0)
|
|
136
|
+
return "issued";
|
|
137
|
+
return paid < total ? "partly_paid" : "paid";
|
|
138
|
+
}, "settledStatus");
|
|
139
|
+
var dayMonth = /* @__PURE__ */ __name((date) => date === null ? null : `${date.slice(8, 10)}.${date.slice(5, 7)}`, "dayMonth");
|
|
140
|
+
var notes = /* @__PURE__ */ __name((...words2) => {
|
|
141
|
+
const kept = words2.filter((word) => word !== null);
|
|
142
|
+
return kept.length === 0 ? "" : ` (${kept.join(", ")})`;
|
|
143
|
+
}, "notes");
|
|
144
|
+
var invoiceLine = /* @__PURE__ */ __name((invoice) => {
|
|
145
|
+
const party = invoice.counterpartyName === null ? "" : `${invoice.direction === "receivable" ? " to" : " from"} ${invoice.counterpartyName}`;
|
|
146
|
+
const due = invoice.dueDate === null ? "" : `, due ${dayMonth(invoice.dueDate)}`;
|
|
147
|
+
return `${invoice.number ?? `#${invoice.id}`} \xB7 ${moneyLabel(invoice.total, invoice.currency)}${party}${due}` + notes(invoice.status.replace("_", " "), invoice.review === "confirmed" ? null : invoice.review);
|
|
148
|
+
}, "invoiceLine");
|
|
149
|
+
var paymentLine = /* @__PURE__ */ __name((payment) => {
|
|
150
|
+
const party = payment.partyName === null ? "" : `${payment.direction === "in" ? " from" : " to"} ${payment.partyName}`;
|
|
151
|
+
return `${moneyLabel(payment.amount, payment.currency)}${party}, ${dayMonth(payment.date)}` + notes(payment.review === "confirmed" ? null : payment.review);
|
|
152
|
+
}, "paymentLine");
|
|
153
|
+
var invoiceTitle = /* @__PURE__ */ __name((invoice) => `Invoice ${invoiceLine(invoice)}`, "invoiceTitle");
|
|
154
|
+
var paymentEntryTitle = /* @__PURE__ */ __name((payment) => `Payment \xB7 ${paymentLine(payment)}`, "paymentEntryTitle");
|
|
155
|
+
|
|
156
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/domain/orders.js
|
|
157
|
+
var ORDER_STATUSES = ["placed", "shipped", "delivered", "cancelled", "returned"];
|
|
158
|
+
var ORDER_PURPOSES = ["personal", "business", "client", "other"];
|
|
159
|
+
var orderLine = /* @__PURE__ */ __name((order) => {
|
|
160
|
+
const money = order.total === null || order.currency === null ? "" : `, ${moneyLabel(order.total, order.currency)}`;
|
|
161
|
+
const notes2 = [order.status, order.review === "confirmed" ? null : order.review].filter(Boolean).join(", ");
|
|
162
|
+
return `${order.number ?? `#${order.id}`} \xB7 ${order.supplierName}${money} (${notes2})`;
|
|
163
|
+
}, "orderLine");
|
|
164
|
+
var orderTitle = /* @__PURE__ */ __name((order) => `Order ${orderLine(order)}`, "orderTitle");
|
|
165
|
+
|
|
166
|
+
// node_modules/.pnpm/@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/types.js
|
|
167
|
+
var QUERY_LIMITS = {
|
|
168
|
+
bytes: 8192,
|
|
169
|
+
depth: 32,
|
|
170
|
+
nodes: 256
|
|
171
|
+
};
|
|
172
|
+
var spanSchema = object({ start: number(), end: number() });
|
|
173
|
+
var predicateSchema = object({
|
|
174
|
+
kind: literal("predicate"),
|
|
175
|
+
field: string(),
|
|
176
|
+
operator: picklist(["term", "phrase", "wildcard", "regex", "range"]),
|
|
177
|
+
value: string(),
|
|
178
|
+
upper: optional(string()),
|
|
179
|
+
lower_inclusive: optional(boolean()),
|
|
180
|
+
upper_inclusive: optional(boolean()),
|
|
181
|
+
span: spanSchema,
|
|
182
|
+
implicit: optional(literal(true)),
|
|
183
|
+
slop: optional(pipe(number(), integer(), minValue(0)))
|
|
184
|
+
});
|
|
185
|
+
var queryNodeSchema = variant("kind", [
|
|
186
|
+
predicateSchema,
|
|
187
|
+
object({
|
|
188
|
+
kind: literal("boolean"),
|
|
189
|
+
clauses: array(object({ occur: picklist(["must", "should", "must_not"]), node: lazy(() => queryNodeSchema) })),
|
|
190
|
+
span: spanSchema
|
|
191
|
+
})
|
|
192
|
+
]);
|
|
193
|
+
var queryAstSchema = object({
|
|
194
|
+
version: literal(1),
|
|
195
|
+
language: literal("lucene-v1"),
|
|
196
|
+
root: queryNodeSchema
|
|
197
|
+
});
|
|
198
|
+
function queryError(reason, span, alternative, context3 = {}, details = {}) {
|
|
199
|
+
throw new CliError("validation_error", `${context3.command ?? "query"}: ${reason} at position ${span.start + 1}${alternative ? ` \u2014 ${alternative}` : ""}`, {
|
|
200
|
+
reason,
|
|
201
|
+
span,
|
|
202
|
+
...alternative ? { alternative } : {},
|
|
203
|
+
...context3.guide ? { guide: context3.guide } : {},
|
|
204
|
+
...details
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
__name(queryError, "queryError");
|
|
208
|
+
var walkQuery = /* @__PURE__ */ __name((node) => node.kind === "predicate" ? [node] : node.clauses.flatMap(({ node: node2 }) => walkQuery(node2)), "walkQuery");
|
|
209
|
+
|
|
210
|
+
// node_modules/.pnpm/@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/dates.js
|
|
211
|
+
var timezoneOf = /* @__PURE__ */ __name((given) => {
|
|
212
|
+
const zone = given ?? Intl.DateTimeFormat().resolvedOptions().timeZone ?? "UTC";
|
|
213
|
+
try {
|
|
214
|
+
new Intl.DateTimeFormat("en", { timeZone: zone }).format(0);
|
|
215
|
+
} catch {
|
|
216
|
+
queryError("query.invalid-timezone", { start: 0, end: 0 }, "use an IANA timezone such as Europe/Madrid");
|
|
217
|
+
}
|
|
218
|
+
return zone;
|
|
219
|
+
}, "timezoneOf");
|
|
220
|
+
var calendar = /* @__PURE__ */ __name((value, span) => {
|
|
221
|
+
if (!/^\d{4}-\d{2}-\d{2}$/u.test(value))
|
|
222
|
+
queryError("query.invalid-date", span, "use an ISO date or a quoted timestamp with offset");
|
|
223
|
+
const year = Number(value.slice(0, 4)), month = Number(value.slice(5, 7)), day = Number(value.slice(8, 10));
|
|
224
|
+
const date = /* @__PURE__ */ new Date(0);
|
|
225
|
+
date.setUTCFullYear(year, month - 1, day);
|
|
226
|
+
date.setUTCHours(0, 0, 0, 0);
|
|
227
|
+
if (date.getUTCFullYear() !== year || date.getUTCMonth() !== month - 1 || date.getUTCDate() !== day)
|
|
228
|
+
queryError("query.invalid-date", span);
|
|
229
|
+
return date;
|
|
230
|
+
}, "calendar");
|
|
231
|
+
var dayBoundary = /* @__PURE__ */ __name((value, zone, next, span) => {
|
|
232
|
+
const date = calendar(value, span);
|
|
233
|
+
if (next)
|
|
234
|
+
date.setUTCDate(date.getUTCDate() + 1);
|
|
235
|
+
const wanted = date.getUTCFullYear() * 1e4 + (date.getUTCMonth() + 1) * 100 + date.getUTCDate();
|
|
236
|
+
const formatter = new Intl.DateTimeFormat("en-CA", {
|
|
237
|
+
timeZone: zone,
|
|
238
|
+
year: "numeric",
|
|
239
|
+
month: "2-digit",
|
|
240
|
+
day: "2-digit",
|
|
241
|
+
era: "short"
|
|
242
|
+
});
|
|
243
|
+
const dayAt = /* @__PURE__ */ __name((time) => {
|
|
244
|
+
const parts = formatter.formatToParts(time);
|
|
245
|
+
const value2 = /* @__PURE__ */ __name((name) => Number(parts.find((p) => p.type === name)?.value), "value");
|
|
246
|
+
const year = parts.find((p) => p.type === "era")?.value === "BC" ? 1 - value2("year") : value2("year");
|
|
247
|
+
return year * 1e4 + value2("month") * 100 + value2("day");
|
|
248
|
+
}, "dayAt");
|
|
249
|
+
let lo = date.getTime() - 2 * 864e5, hi = date.getTime() + 2 * 864e5;
|
|
250
|
+
while (lo < hi) {
|
|
251
|
+
const mid = Math.floor((lo + hi) / 2);
|
|
252
|
+
if (dayAt(mid) < wanted)
|
|
253
|
+
lo = mid + 1;
|
|
254
|
+
else
|
|
255
|
+
hi = mid;
|
|
256
|
+
}
|
|
257
|
+
if (dayAt(lo) !== wanted)
|
|
258
|
+
queryError("query.invalid-date", span, "this calendar day does not exist in the selected timezone");
|
|
259
|
+
return lo;
|
|
260
|
+
}, "dayBoundary");
|
|
261
|
+
var WALL = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,3}))?)?$/u;
|
|
262
|
+
var wallTime = /* @__PURE__ */ __name((value, zone, span) => {
|
|
263
|
+
const [, year, month, day, hour, minute, second = "0", fraction = "0"] = WALL.exec(value) ?? [];
|
|
264
|
+
if (year === void 0)
|
|
265
|
+
queryError("query.invalid-date", span, "use YYYY-MM-DDTHH:mm, with optional seconds");
|
|
266
|
+
const wanted = Date.UTC(Number(year), Number(month) - 1, Number(day), Number(hour), Number(minute), Number(second), Number(fraction.padEnd(3, "0")));
|
|
267
|
+
const check = new Date(wanted);
|
|
268
|
+
if (check.getUTCDate() !== Number(day) || check.getUTCHours() !== Number(hour) || check.getUTCMinutes() !== Number(minute) || check.getUTCSeconds() !== Number(second))
|
|
269
|
+
queryError("query.invalid-date", span);
|
|
270
|
+
const formatter = new Intl.DateTimeFormat("en-CA", {
|
|
271
|
+
timeZone: zone,
|
|
272
|
+
year: "numeric",
|
|
273
|
+
month: "2-digit",
|
|
274
|
+
day: "2-digit",
|
|
275
|
+
hour: "2-digit",
|
|
276
|
+
minute: "2-digit",
|
|
277
|
+
second: "2-digit",
|
|
278
|
+
hourCycle: "h23"
|
|
279
|
+
});
|
|
280
|
+
const shown = /* @__PURE__ */ __name((instant) => {
|
|
281
|
+
const parts = Object.fromEntries(formatter.formatToParts(instant).map((part) => [part.type, Number(part.value)]));
|
|
282
|
+
return Date.UTC(parts.year ?? 0, (parts.month ?? 1) - 1, parts.day, parts.hour, parts.minute, parts.second) + (instant % 1e3 + 1e3) % 1e3;
|
|
283
|
+
}, "shown");
|
|
284
|
+
const found = /* @__PURE__ */ new Set();
|
|
285
|
+
for (const probe of [wanted - 864e5, wanted, wanted + 864e5]) {
|
|
286
|
+
const candidate = wanted - (shown(probe) - probe);
|
|
287
|
+
if (shown(candidate) === wanted)
|
|
288
|
+
found.add(candidate);
|
|
289
|
+
}
|
|
290
|
+
if (found.size !== 1)
|
|
291
|
+
queryError("query.invalid-date", span, "this local time is skipped or repeated by daylight saving; add an offset");
|
|
292
|
+
return [...found][0];
|
|
293
|
+
}, "wallTime");
|
|
294
|
+
var ZONED = /(?:Z|[+-]\d{2}:?\d{2})$/iu;
|
|
295
|
+
var zonedMoment = /* @__PURE__ */ __name((value, zone, span, { end = false } = {}) => {
|
|
296
|
+
if (/^\d{4}-\d{2}-\d{2}$/u.test(value))
|
|
297
|
+
return dayBoundary(value, zone, end, span) - (end ? 1 : 0);
|
|
298
|
+
if (!ZONED.test(value))
|
|
299
|
+
return wallTime(value, zone, span);
|
|
300
|
+
const time = Date.parse(value);
|
|
301
|
+
if (!/^\d{4}-\d{2}-\d{2}T/u.test(value) || !Number.isFinite(time))
|
|
302
|
+
queryError("query.invalid-date", span);
|
|
303
|
+
calendar(value.slice(0, 10), span);
|
|
304
|
+
return time;
|
|
305
|
+
}, "zonedMoment");
|
|
306
|
+
var AGO = /^(\d+)(m|h|d)$/u;
|
|
307
|
+
var AGO_MS = { m: 6e4, h: 36e5, d: 864e5 };
|
|
308
|
+
var dayOf = /* @__PURE__ */ __name((word, zone, now, span) => {
|
|
309
|
+
const today = new Intl.DateTimeFormat("en-CA", {
|
|
310
|
+
timeZone: zone,
|
|
311
|
+
year: "numeric",
|
|
312
|
+
month: "2-digit",
|
|
313
|
+
day: "2-digit"
|
|
314
|
+
}).format(now);
|
|
315
|
+
if (word === "today")
|
|
316
|
+
return today;
|
|
317
|
+
const date = calendar(today, span);
|
|
318
|
+
date.setUTCDate(date.getUTCDate() - 1);
|
|
319
|
+
return date.toISOString().slice(0, 10);
|
|
320
|
+
}, "dayOf");
|
|
321
|
+
var dateEndpoint = /* @__PURE__ */ __name((value, zone, side, inclusive, span, now = Date.now()) => {
|
|
322
|
+
if (value === "*")
|
|
323
|
+
return { inclusive };
|
|
324
|
+
const word = value.toLowerCase();
|
|
325
|
+
if (word === "today" || word === "yesterday")
|
|
326
|
+
return dateEndpoint(dayOf(word, zone, now, span), zone, side, inclusive, span);
|
|
327
|
+
const [, amount, unit] = AGO.exec(word) ?? [];
|
|
328
|
+
if (amount && unit)
|
|
329
|
+
return { time: now - Number(amount) * (AGO_MS[unit] ?? 0), inclusive };
|
|
330
|
+
if (/^\d{4}-\d{2}-\d{2}$/u.test(value))
|
|
331
|
+
return {
|
|
332
|
+
time: dayBoundary(value, zone, side === "lower" ? !inclusive : inclusive, span),
|
|
333
|
+
inclusive: side === "lower"
|
|
334
|
+
};
|
|
335
|
+
if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/u.test(value))
|
|
336
|
+
queryError("query.invalid-date", span, "use an ISO date, today, yesterday, 30m/2h/7d ago, or a quoted timestamp with offset");
|
|
337
|
+
calendar(value.slice(0, 10), span);
|
|
338
|
+
const time = Date.parse(value);
|
|
339
|
+
if (!Number.isFinite(time) || Number(value.slice(11, 13)) > 23 || Number(value.slice(14, 16)) > 59 || Number(value.slice(17, 19)) > 59)
|
|
340
|
+
queryError("query.invalid-date", span);
|
|
341
|
+
return { time, inclusive };
|
|
342
|
+
}, "dateEndpoint");
|
|
343
|
+
var dateRange = /* @__PURE__ */ __name((lower, upper, lowerInclusive, upperInclusive, zone, span, now = Date.now()) => {
|
|
344
|
+
const since = lower === upper && AGO.test(lower.toLowerCase());
|
|
345
|
+
const lo = dateEndpoint(lower, zone, "lower", lowerInclusive, span, now);
|
|
346
|
+
const hi = dateEndpoint(since ? "*" : upper, zone, "upper", upperInclusive, span, now);
|
|
347
|
+
return {
|
|
348
|
+
...lo.time === void 0 ? {} : { lower: lo.time },
|
|
349
|
+
...hi.time === void 0 ? {} : { upper: hi.time },
|
|
350
|
+
lower_inclusive: lo.inclusive,
|
|
351
|
+
upper_inclusive: hi.inclusive
|
|
352
|
+
};
|
|
353
|
+
}, "dateRange");
|
|
354
|
+
|
|
355
|
+
// node_modules/.pnpm/@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/fields.js
|
|
356
|
+
var FIELD_TYPES = ["kw", "txt", "enum", "num", "time", "bool", "ref"];
|
|
357
|
+
var OPERATORS_BY_TYPE = {
|
|
358
|
+
kw: ["term", "phrase", "wildcard"],
|
|
359
|
+
txt: ["term", "phrase", "wildcard"],
|
|
360
|
+
enum: ["term"],
|
|
361
|
+
num: ["term", "range"],
|
|
362
|
+
time: ["term", "range"],
|
|
363
|
+
bool: ["term"],
|
|
364
|
+
ref: ["term", "phrase"]
|
|
365
|
+
};
|
|
366
|
+
var QUERY_BACKENDS = ["sql", "native"];
|
|
367
|
+
var unwrap = /* @__PURE__ */ __name((schema) => schema.wrapped ? unwrap(schema.wrapped) : schema, "unwrap");
|
|
368
|
+
var REFERENCE_SOURCE = reference.pipe[1].requirement.source;
|
|
369
|
+
var typeOf = /* @__PURE__ */ __name((schema) => {
|
|
370
|
+
const plain = unwrap(schema);
|
|
371
|
+
const actions = plain.pipe ?? [];
|
|
372
|
+
switch (plain.type) {
|
|
373
|
+
case "picklist":
|
|
374
|
+
return { type: "enum", values: (plain.options ?? []).map(String) };
|
|
375
|
+
case "number":
|
|
376
|
+
return { type: "num" };
|
|
377
|
+
case "boolean":
|
|
378
|
+
return { type: "bool" };
|
|
379
|
+
case "string":
|
|
380
|
+
if (actions.some((action) => action.type === "iso_timestamp"))
|
|
381
|
+
return { type: "time" };
|
|
382
|
+
if (actions.some((action) => action.requirement instanceof RegExp && action.requirement.source === REFERENCE_SOURCE))
|
|
383
|
+
return { type: "ref" };
|
|
384
|
+
return { type: "kw" };
|
|
385
|
+
case "array":
|
|
386
|
+
return plain.item ? typeOf(plain.item) : void 0;
|
|
387
|
+
default:
|
|
388
|
+
return void 0;
|
|
389
|
+
}
|
|
390
|
+
}, "typeOf");
|
|
391
|
+
var exampleOf = /* @__PURE__ */ __name((name, type, values) => ({
|
|
392
|
+
kw: `${name}:abc`,
|
|
393
|
+
txt: `${name}:word*`,
|
|
394
|
+
enum: `${name}:${values?.[0] ?? "x"}`,
|
|
395
|
+
num: `${name}>0`,
|
|
396
|
+
time: `${name}>=7d`,
|
|
397
|
+
bool: `${name}:true`,
|
|
398
|
+
ref: `${name}:"note:42"`
|
|
399
|
+
})[type], "exampleOf");
|
|
400
|
+
var queryFieldsOf = /* @__PURE__ */ __name((schema, annotations = {}) => {
|
|
401
|
+
const entries = unwrap(schema).entries ?? {};
|
|
402
|
+
const excluded = new Set(annotations.exclude ?? []);
|
|
403
|
+
const words2 = new Set(annotations.text ?? []);
|
|
404
|
+
const native = new Set(annotations.native ?? []);
|
|
405
|
+
const negatable = new Set(annotations.negatable ?? []);
|
|
406
|
+
const finish = /* @__PURE__ */ __name((field) => ({
|
|
407
|
+
...field,
|
|
408
|
+
operators: OPERATORS_BY_TYPE[field.type],
|
|
409
|
+
example: annotations.examples?.[field.name] ?? field.example ?? exampleOf(field.name, field.type, field.values),
|
|
410
|
+
...native.has(field.name) ? { native: true } : {},
|
|
411
|
+
...negatable.has(field.name) ? { negatable: true } : {},
|
|
412
|
+
...annotations.validate?.[field.name] ? { validate: annotations.validate[field.name] } : {}
|
|
413
|
+
}), "finish");
|
|
414
|
+
const own = Object.entries(entries).flatMap(([name, entry]) => {
|
|
415
|
+
if (excluded.has(name))
|
|
416
|
+
return [];
|
|
417
|
+
const found = typeOf(entry);
|
|
418
|
+
if (!found)
|
|
419
|
+
return [];
|
|
420
|
+
return [finish({ name, ...found, ...words2.has(name) && found.type === "kw" ? { type: "txt" } : {} })];
|
|
421
|
+
});
|
|
422
|
+
const relations = Object.entries(annotations.relations ?? {}).map(([name, relation]) => finish({ name, ...relation }));
|
|
423
|
+
const states = annotations.states ? [
|
|
424
|
+
finish({
|
|
425
|
+
name: "is",
|
|
426
|
+
type: "enum",
|
|
427
|
+
values: Object.keys(annotations.states),
|
|
428
|
+
relation: Object.entries(annotations.states).map(([state, meaning]) => `${state}: ${meaning}`).join("; ")
|
|
429
|
+
})
|
|
430
|
+
] : [];
|
|
431
|
+
return [...own, ...relations, ...states];
|
|
432
|
+
}, "queryFieldsOf");
|
|
433
|
+
|
|
434
|
+
// node_modules/.pnpm/@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/help.js
|
|
435
|
+
var shownOf = /* @__PURE__ */ __name((registry) => registry.backend === "native" ? registry.fields.filter((field) => field.native) : registry.fields, "shownOf");
|
|
436
|
+
var leftOut = /* @__PURE__ */ __name((fields) => fields.filter((field) => field.negatable).map((field) => field.name), "leftOut");
|
|
437
|
+
var has = /* @__PURE__ */ __name((fields, operator) => fields.some((field) => field.operators.includes(operator)), "has");
|
|
438
|
+
var syntaxOf = /* @__PURE__ */ __name((shown, backend) => [
|
|
439
|
+
"field:value",
|
|
440
|
+
...has(shown, "phrase") ? ['"a phrase"'] : [],
|
|
441
|
+
...has(shown, "wildcard") ? ["word*"] : [],
|
|
442
|
+
...backend === "native" ? ["terms joined by AND"] : ["AND OR NOT", "( )"],
|
|
443
|
+
...has(shown, "range") ? ["[a TO b] \xB7 > >= < <="] : []
|
|
444
|
+
].join(" \xB7 "), "syntaxOf");
|
|
445
|
+
var kindOf = /* @__PURE__ */ __name((field) => field.values ? `${field.type}: ${field.values.join("|")}` : `${field.type}: ${field.operators.join(", ")}`, "kindOf");
|
|
446
|
+
var fieldsHelp = /* @__PURE__ */ __name((registry, guide) => {
|
|
447
|
+
const shown = shownOf(registry);
|
|
448
|
+
const negatable = leftOut(shown);
|
|
449
|
+
const rows = shown.map((field) => [field.name, kindOf(field), field.example]);
|
|
450
|
+
const widths = [0, 1].map((at) => Math.max(...rows.map((row) => (row[at] ?? "").length)));
|
|
451
|
+
return [
|
|
452
|
+
"Fields:",
|
|
453
|
+
...rows.map(([name = "", kind = "", example = ""]) => ` ${name.padEnd(widths[0] ?? 0)} ${kind.padEnd(widths[1] ?? 0)} ${example}`.trimEnd()),
|
|
454
|
+
...registry.defaults && registry.defaults.length > 0 ? [`Defaults: ${registry.defaults.join(" ")} \u2014 name the field to change it`] : [],
|
|
455
|
+
...negatable.length > 0 ? [`Leave out: -${negatable[0]}:value or NOT ${negatable[0]}:value, for ${negatable.join(", ")}`] : [],
|
|
456
|
+
`Syntax: ${syntaxOf(shown, registry.backend)}`,
|
|
457
|
+
...guide ? [`Guide: ${guide}`] : []
|
|
458
|
+
].join("\n");
|
|
459
|
+
}, "fieldsHelp");
|
|
460
|
+
var queryDescription = /* @__PURE__ */ __name((registry) => {
|
|
461
|
+
const shown = shownOf(registry);
|
|
462
|
+
if (shown.length === 0)
|
|
463
|
+
return "field:value terms; this list filters by none yet, so any term is refused";
|
|
464
|
+
const negatable = leftOut(shown);
|
|
465
|
+
const terms = registry.backend === "native" ? `field:value terms joined by AND that narrow the list${negatable.length > 0 ? `; -field:value or NOT field:value leaves out what matches, for ${negatable.join(", ")} only` : ""}` : `field:value terms that narrow the list (Lucene: AND OR NOT, -field:value${has(shown, "range") ? ", [a TO b], > <" : ""})`;
|
|
466
|
+
const fields = shown.map((field) => field.values ? `${field.name} (${field.values.join("|")})` : field.name);
|
|
467
|
+
const defaults = registry.defaults?.length ? `; unless named: ${registry.defaults.join(" ")}` : "";
|
|
468
|
+
return `${terms}; fields: ${fields.join(", ")}; e.g. ${shown[0]?.example ?? ""}${defaults}`;
|
|
469
|
+
}, "queryDescription");
|
|
470
|
+
|
|
471
|
+
// node_modules/.pnpm/@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/validate.js
|
|
472
|
+
var inContext = /* @__PURE__ */ __name((context3, run2) => {
|
|
473
|
+
try {
|
|
474
|
+
run2();
|
|
475
|
+
} catch (failure) {
|
|
476
|
+
if (!isCliError(failure) || typeof failure.details.reason !== "string" || failure.details.span === void 0)
|
|
477
|
+
throw failure;
|
|
478
|
+
const { reason, span, alternative } = failure.details;
|
|
479
|
+
queryError(reason, span, alternative, context3);
|
|
480
|
+
}
|
|
481
|
+
}, "inContext");
|
|
482
|
+
var bounds = /* @__PURE__ */ __name((node) => node.operator === "range" ? [node.value, node.upper ?? "*"].filter((bound) => bound !== "*") : [node.value], "bounds");
|
|
483
|
+
var checkValue = /* @__PURE__ */ __name((field, node, options) => {
|
|
484
|
+
const fail = /* @__PURE__ */ __name((reason, alternative) => queryError(reason, node.span, alternative, options), "fail");
|
|
485
|
+
if (node.value === "" && field.type !== "txt")
|
|
486
|
+
fail("query.missing-value");
|
|
487
|
+
if (node.operator === "wildcard")
|
|
488
|
+
return;
|
|
489
|
+
switch (field.type) {
|
|
490
|
+
case "enum":
|
|
491
|
+
if (!field.values?.includes(node.value.toLowerCase()))
|
|
492
|
+
fail("query.unknown-value", `${field.name} takes ${field.values?.join(", ")}`);
|
|
493
|
+
return;
|
|
494
|
+
case "bool":
|
|
495
|
+
if (!["true", "false"].includes(node.value.toLowerCase()))
|
|
496
|
+
fail("query.unknown-value", `${field.name} takes true, false`);
|
|
497
|
+
return;
|
|
498
|
+
case "num":
|
|
499
|
+
for (const bound of bounds(node))
|
|
500
|
+
if (!Number.isFinite(Number(bound)) || bound.trim() === "")
|
|
501
|
+
fail("query.invalid-number", `${field.name} takes a number`);
|
|
502
|
+
return;
|
|
503
|
+
case "time":
|
|
504
|
+
inContext(options, () => {
|
|
505
|
+
for (const bound of bounds(node))
|
|
506
|
+
dateEndpoint(bound, options.zone ?? "UTC", "lower", true, node.span);
|
|
507
|
+
});
|
|
508
|
+
return;
|
|
509
|
+
default:
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
}, "checkValue");
|
|
513
|
+
var validateQuery = /* @__PURE__ */ __name((ast, registry, options = {}) => {
|
|
514
|
+
const byName = new Map(registry.fields.map((field) => [field.name, field]));
|
|
515
|
+
const visit = /* @__PURE__ */ __name((node, required) => {
|
|
516
|
+
if (node.kind === "boolean") {
|
|
517
|
+
for (const clause of node.clauses)
|
|
518
|
+
visit(clause.node, required && clause.occur === "must");
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
const field = byName.get(node.field);
|
|
522
|
+
if (!field)
|
|
523
|
+
queryError("query.unknown-field", node.span, `no field "${node.field}"`, options, {
|
|
524
|
+
fields: registry.fields.map((one) => one.name)
|
|
525
|
+
});
|
|
526
|
+
if (registry.backend === "native" && !field.native)
|
|
527
|
+
queryError("query.unsupported-field", node.span, `the source cannot filter by ${field.name}`, options, {
|
|
528
|
+
supported: registry.fields.filter((one) => one.native).map((one) => one.name)
|
|
529
|
+
});
|
|
530
|
+
const presence = node.operator === "wildcard" && node.value === "*";
|
|
531
|
+
if (!presence && !field.operators.includes(node.operator))
|
|
532
|
+
queryError("query.unsupported-operator", node.span, `${field.name} takes ${field.operators.join(", ")}`, options);
|
|
533
|
+
if (field.placement === "and" && !required)
|
|
534
|
+
queryError("query.unsupported-placement", node.span, `${field.name} only as a required term, not under OR or NOT`, options);
|
|
535
|
+
if (presence)
|
|
536
|
+
return;
|
|
537
|
+
checkValue(field, node, options);
|
|
538
|
+
if (field.validate)
|
|
539
|
+
inContext(options, () => field.validate?.(node));
|
|
540
|
+
}, "visit");
|
|
541
|
+
visit(ast.root, true);
|
|
542
|
+
return ast;
|
|
543
|
+
}, "validateQuery");
|
|
544
|
+
var fieldsNamed = /* @__PURE__ */ __name((ast) => new Set(walkQuery(ast.root).map((node) => node.field)), "fieldsNamed");
|
|
545
|
+
|
|
546
|
+
// node_modules/.pnpm/@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/parser.js
|
|
547
|
+
var whitespace = /* @__PURE__ */ __name((c) => /[ \t\n\r\u3000]/u.test(c), "whitespace");
|
|
548
|
+
var reserved = /* @__PURE__ */ new Set([
|
|
549
|
+
"+",
|
|
550
|
+
"-",
|
|
551
|
+
"!",
|
|
552
|
+
"(",
|
|
553
|
+
")",
|
|
554
|
+
":",
|
|
555
|
+
"=",
|
|
556
|
+
"^",
|
|
557
|
+
"@",
|
|
558
|
+
"<",
|
|
559
|
+
">",
|
|
560
|
+
"[",
|
|
561
|
+
"]",
|
|
562
|
+
'"',
|
|
563
|
+
"{",
|
|
564
|
+
"}",
|
|
565
|
+
"~",
|
|
566
|
+
"\\",
|
|
567
|
+
"/"
|
|
568
|
+
]);
|
|
569
|
+
var decodeEscapes = /* @__PURE__ */ __name((raw, span, fail) => {
|
|
570
|
+
let out = "";
|
|
571
|
+
for (let at = 0; at < raw.length; at++) {
|
|
572
|
+
if (raw[at] !== "\\") {
|
|
573
|
+
out += raw[at];
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
if (++at >= raw.length)
|
|
577
|
+
fail("query.invalid-escape", span);
|
|
578
|
+
if (raw[at] === "u") {
|
|
579
|
+
const hex = raw.slice(at + 1, at + 5);
|
|
580
|
+
if (!/^[0-9a-fA-F]{4}$/.test(hex))
|
|
581
|
+
fail("query.invalid-escape", span);
|
|
582
|
+
out += String.fromCharCode(Number.parseInt(hex, 16));
|
|
583
|
+
at += 4;
|
|
584
|
+
} else
|
|
585
|
+
out += raw[at];
|
|
586
|
+
}
|
|
587
|
+
return out;
|
|
588
|
+
}, "decodeEscapes");
|
|
589
|
+
var tokensOf = /* @__PURE__ */ __name((text5, fail = queryError) => {
|
|
590
|
+
const tokens = [];
|
|
591
|
+
let at = 0;
|
|
592
|
+
let range = false;
|
|
593
|
+
while (at < text5.length) {
|
|
594
|
+
const start = at;
|
|
595
|
+
const c = text5[at] ?? "";
|
|
596
|
+
if (whitespace(c)) {
|
|
597
|
+
at++;
|
|
598
|
+
continue;
|
|
599
|
+
}
|
|
600
|
+
let kind = c;
|
|
601
|
+
if (c === '"' || !range && c === "/") {
|
|
602
|
+
at++;
|
|
603
|
+
while (at < text5.length && text5[at] !== c) {
|
|
604
|
+
if (text5[at] === "\\" && (c === '"' || text5[at + 1] === "/"))
|
|
605
|
+
at++;
|
|
606
|
+
at++;
|
|
607
|
+
}
|
|
608
|
+
if (at >= text5.length)
|
|
609
|
+
fail("query.unclosed-literal", { start, end: at }, c === "/" ? regexHint(text5, start) : void 0);
|
|
610
|
+
at++;
|
|
611
|
+
if (c === "/" && /^[dgimsuvy]+(?:$|[ \t\n\r)])/.test(text5.slice(at)))
|
|
612
|
+
fail("query.unsupported-regex-flags", { start: at, end: at + 1 }, "Lucene regex does not take JavaScript flags");
|
|
613
|
+
kind = c === '"' ? "quoted" : "regex";
|
|
614
|
+
} else if (range && c !== "]" && c !== "}") {
|
|
615
|
+
while (at < text5.length && !whitespace(text5[at] ?? "") && !["]", "}"].includes(text5[at] ?? ""))
|
|
616
|
+
at++;
|
|
617
|
+
kind = "rangeValue";
|
|
618
|
+
} else if (reserved.has(c)) {
|
|
619
|
+
if (c === "\\") {
|
|
620
|
+
at += 2;
|
|
621
|
+
while (at < text5.length && !whitespace(text5[at] ?? "") && (!reserved.has(text5[at] ?? "") || ["+", "-"].includes(text5[at] ?? "")))
|
|
622
|
+
at++;
|
|
623
|
+
kind = "term";
|
|
624
|
+
} else {
|
|
625
|
+
at++;
|
|
626
|
+
if ((c === "<" || c === ">") && text5[at] === "=") {
|
|
627
|
+
at++;
|
|
628
|
+
kind += "=";
|
|
629
|
+
}
|
|
630
|
+
if (c === "[" || c === "{")
|
|
631
|
+
range = true;
|
|
632
|
+
if (c === "]" || c === "}")
|
|
633
|
+
range = false;
|
|
634
|
+
}
|
|
635
|
+
} else {
|
|
636
|
+
at++;
|
|
637
|
+
while (at < text5.length) {
|
|
638
|
+
const next = text5[at] ?? "";
|
|
639
|
+
if (next === "\\") {
|
|
640
|
+
if (at + 1 >= text5.length)
|
|
641
|
+
fail("query.invalid-escape", { start: at, end: at + 1 });
|
|
642
|
+
at += 2;
|
|
643
|
+
continue;
|
|
644
|
+
}
|
|
645
|
+
if (next === "@" && new RegExp("^@(?:\\p{L}|[\\p{L}\\p{N}][^\\s@]*\\.[\\p{L}\\p{N}])", "u").test(text5.slice(at))) {
|
|
646
|
+
at++;
|
|
647
|
+
continue;
|
|
648
|
+
}
|
|
649
|
+
if (whitespace(next) || reserved.has(next) && next !== "+" && next !== "-")
|
|
650
|
+
break;
|
|
651
|
+
at++;
|
|
652
|
+
}
|
|
653
|
+
const [field, colon] = tokens.slice(-2);
|
|
654
|
+
if (field?.kind === "term" && colon?.kind === ":" && colon.span.end === start && text5[at] === ":" && /^[a-z][a-z_-]*$/u.test(text5.slice(start, at)) && /^:[^\s()"]/u.test(text5.slice(at)))
|
|
655
|
+
while (at < text5.length && !whitespace(text5[at] ?? "") && !["(", ")", '"'].includes(text5[at] ?? ""))
|
|
656
|
+
at++;
|
|
657
|
+
const raw = text5.slice(start, at);
|
|
658
|
+
kind = { AND: "AND", OR: "OR", NOT: "NOT", "&&": "AND", "||": "OR" }[raw] ?? (/^\d+(?:\.\d+)?$/u.test(raw) ? "number" : "term");
|
|
659
|
+
}
|
|
660
|
+
tokens.push({ kind, raw: text5.slice(start, at), span: { start, end: at } });
|
|
661
|
+
}
|
|
662
|
+
tokens.push({ kind: "EOF", raw: "", span: { start: at, end: at } });
|
|
663
|
+
return tokens;
|
|
664
|
+
}, "tokensOf");
|
|
665
|
+
var quoteHint = /* @__PURE__ */ __name((text5, at) => {
|
|
666
|
+
for (const match of text5.matchAll(/(?<=^|[\s(])([\p{L}\p{N}_.-]+):([^\s"()]+)/gu)) {
|
|
667
|
+
const [whole, field, value = ""] = match;
|
|
668
|
+
if (at < match.index || at > match.index + whole.length)
|
|
669
|
+
continue;
|
|
670
|
+
return /[:=/?*~^@<>![\]{}\\]/u.test(value) ? `put the value in quotes: ${field}:"${value}"` : void 0;
|
|
671
|
+
}
|
|
672
|
+
return void 0;
|
|
673
|
+
}, "quoteHint");
|
|
674
|
+
var regexHint = /* @__PURE__ */ __name((text5, at) => {
|
|
675
|
+
const word = `${/[^\s()"]*$/u.exec(text5.slice(0, at))?.[0] ?? ""}${/^[^\s()"]*/u.exec(text5.slice(at))?.[0] ?? ""}`;
|
|
676
|
+
return quoteHint(text5, at) ?? `/ starts a regular expression; put the value in quotes: "${word}"`;
|
|
677
|
+
}, "regexHint");
|
|
678
|
+
var parseLucene = /* @__PURE__ */ __name((text5, { defaultField = "text", proximity = false, ...context3 } = {}) => {
|
|
679
|
+
const fail = /* @__PURE__ */ __name((reason, span, alternative) => queryError(reason, span, alternative ?? quoteHint(text5, span.start), context3), "fail");
|
|
680
|
+
if (text5.length > QUERY_LIMITS.bytes || new TextEncoder().encode(text5).length > QUERY_LIMITS.bytes)
|
|
681
|
+
fail("query.too-large", { start: 0, end: text5.length });
|
|
682
|
+
const tokens = tokensOf(text5, fail);
|
|
683
|
+
let at = 0;
|
|
684
|
+
let count6 = 0;
|
|
685
|
+
let depth = 0;
|
|
686
|
+
const peek = /* @__PURE__ */ __name(() => tokens[at], "peek");
|
|
687
|
+
const take = /* @__PURE__ */ __name(() => tokens[at++], "take");
|
|
688
|
+
const expect = /* @__PURE__ */ __name((kind) => {
|
|
689
|
+
if (peek().kind !== kind)
|
|
690
|
+
fail("query.invalid-syntax", peek().span);
|
|
691
|
+
return take();
|
|
692
|
+
}, "expect");
|
|
693
|
+
const built = /* @__PURE__ */ __name((node) => {
|
|
694
|
+
if (++count6 > QUERY_LIMITS.nodes)
|
|
695
|
+
fail("query.too-large", node.span);
|
|
696
|
+
return node;
|
|
697
|
+
}, "built");
|
|
698
|
+
const combine = /* @__PURE__ */ __name((clauses, occur) => {
|
|
699
|
+
const first = clauses[0];
|
|
700
|
+
const last = clauses.at(-1);
|
|
701
|
+
if (!first || !last)
|
|
702
|
+
fail("query.invalid-syntax", peek().span);
|
|
703
|
+
if (clauses.length === 1)
|
|
704
|
+
return first;
|
|
705
|
+
return {
|
|
706
|
+
node: built({
|
|
707
|
+
kind: "boolean",
|
|
708
|
+
clauses: clauses.map(({ node, modifier }) => ({ node, occur: modifier ?? occur })),
|
|
709
|
+
span: { start: first.node.span.start, end: last.node.span.end }
|
|
710
|
+
})
|
|
711
|
+
};
|
|
712
|
+
}, "combine");
|
|
713
|
+
const query = /* @__PURE__ */ __name((field, implicit = false) => {
|
|
714
|
+
if (++depth > QUERY_LIMITS.depth)
|
|
715
|
+
fail("query.too-large", peek().span);
|
|
716
|
+
const clauses = [];
|
|
717
|
+
do {
|
|
718
|
+
clauses.push(disjunction(field, implicit));
|
|
719
|
+
} while (!["EOF", ")"].includes(peek().kind));
|
|
720
|
+
const result = combine(clauses, "must");
|
|
721
|
+
depth--;
|
|
722
|
+
if (result.modifier === "must_not")
|
|
723
|
+
return built({ kind: "boolean", clauses: [{ node: result.node, occur: "must_not" }], span: result.node.span });
|
|
724
|
+
return result.node;
|
|
725
|
+
}, "query");
|
|
726
|
+
const disjunction = /* @__PURE__ */ __name((field, implicit) => {
|
|
727
|
+
const clauses = [conjunction(field, implicit)];
|
|
728
|
+
while (peek().kind === "OR") {
|
|
729
|
+
take();
|
|
730
|
+
clauses.push(conjunction(field, implicit));
|
|
731
|
+
}
|
|
732
|
+
return combine(clauses, "should");
|
|
733
|
+
}, "disjunction");
|
|
734
|
+
const conjunction = /* @__PURE__ */ __name((field, implicit) => {
|
|
735
|
+
const clauses = [clause(field, implicit)];
|
|
736
|
+
while (peek().kind === "AND") {
|
|
737
|
+
take();
|
|
738
|
+
clauses.push(clause(field, implicit));
|
|
739
|
+
}
|
|
740
|
+
return combine(clauses, "must");
|
|
741
|
+
}, "conjunction");
|
|
742
|
+
const clause = /* @__PURE__ */ __name((inherited, inheritedImplicit) => {
|
|
743
|
+
let modifier;
|
|
744
|
+
if (["+", "-", "NOT", "!"].includes(peek().kind))
|
|
745
|
+
modifier = take().kind === "+" ? "must" : "must_not";
|
|
746
|
+
let field = inherited;
|
|
747
|
+
let start;
|
|
748
|
+
let implicit = inheritedImplicit;
|
|
749
|
+
if (peek().kind === "term" && [":", "=", "<", ">", "<=", ">="].includes(tokens[at + 1]?.kind ?? "")) {
|
|
750
|
+
const token = take();
|
|
751
|
+
field = decodeEscapes(token.raw, token.span, fail);
|
|
752
|
+
start = token.span.start;
|
|
753
|
+
implicit = false;
|
|
754
|
+
let operator = take();
|
|
755
|
+
if (operator.kind === ":" && ["<", ">", "<=", ">="].includes(peek().kind))
|
|
756
|
+
operator = take();
|
|
757
|
+
if (["<", ">", "<=", ">="].includes(operator.kind)) {
|
|
758
|
+
const value = take();
|
|
759
|
+
if (!["term", "number", "quoted"].includes(value.kind))
|
|
760
|
+
fail("query.invalid-syntax", value.span);
|
|
761
|
+
const decoded = decodeEscapes(value.kind === "quoted" ? value.raw.slice(1, -1) : value.raw, value.span, fail);
|
|
762
|
+
const lower = operator.kind.startsWith(">");
|
|
763
|
+
const node2 = built({
|
|
764
|
+
kind: "predicate",
|
|
765
|
+
field,
|
|
766
|
+
operator: "range",
|
|
767
|
+
value: lower ? decoded : "*",
|
|
768
|
+
upper: lower ? "*" : decoded,
|
|
769
|
+
lower_inclusive: !lower || operator.kind.endsWith("="),
|
|
770
|
+
upper_inclusive: lower || operator.kind.endsWith("="),
|
|
771
|
+
span: { start: token.span.start, end: value.span.end }
|
|
772
|
+
});
|
|
773
|
+
return { node: node2, ...modifier ? { modifier } : {} };
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
let node;
|
|
777
|
+
if (peek().kind === "(") {
|
|
778
|
+
const start2 = take().span.start;
|
|
779
|
+
node = query(field, implicit);
|
|
780
|
+
const end = expect(")").span.end;
|
|
781
|
+
node = { ...node, span: { start: start2, end } };
|
|
782
|
+
} else if (["[", "{"].includes(peek().kind)) {
|
|
783
|
+
const opening = take();
|
|
784
|
+
const lower = take();
|
|
785
|
+
if (!["rangeValue", "quoted"].includes(lower.kind))
|
|
786
|
+
fail("query.invalid-syntax", lower.span);
|
|
787
|
+
const separator = take();
|
|
788
|
+
if (separator.raw !== "TO")
|
|
789
|
+
fail("query.invalid-syntax", separator.span);
|
|
790
|
+
const upper = take();
|
|
791
|
+
if (!["rangeValue", "quoted"].includes(upper.kind))
|
|
792
|
+
fail("query.invalid-syntax", upper.span);
|
|
793
|
+
const closing = take();
|
|
794
|
+
if (!["]", "}"].includes(closing.kind))
|
|
795
|
+
fail("query.invalid-syntax", closing.span);
|
|
796
|
+
const decode = /* @__PURE__ */ __name((t) => decodeEscapes(t.kind === "quoted" ? t.raw.slice(1, -1) : t.raw, t.span, fail), "decode");
|
|
797
|
+
node = built({
|
|
798
|
+
kind: "predicate",
|
|
799
|
+
field,
|
|
800
|
+
operator: "range",
|
|
801
|
+
value: decode(lower),
|
|
802
|
+
upper: decode(upper),
|
|
803
|
+
lower_inclusive: opening.kind === "[",
|
|
804
|
+
upper_inclusive: closing.kind === "]",
|
|
805
|
+
span: { start: start ?? opening.span.start, end: closing.span.end }
|
|
806
|
+
});
|
|
807
|
+
} else {
|
|
808
|
+
const token = take();
|
|
809
|
+
if (!["term", "number", "quoted", "regex"].includes(token.kind))
|
|
810
|
+
fail("query.invalid-syntax", token.span);
|
|
811
|
+
const raw = ["term", "number"].includes(token.kind) ? token.raw : token.raw.slice(1, -1);
|
|
812
|
+
if (field === "fn")
|
|
813
|
+
fail("query.unsupported-operator", token.span, "interval functions are not supported");
|
|
814
|
+
const wildcard = ["term", "number"].includes(token.kind) && /(?<!\\)[*?]/u.test(raw);
|
|
815
|
+
node = built({
|
|
816
|
+
kind: "predicate",
|
|
817
|
+
field,
|
|
818
|
+
operator: token.kind === "regex" ? "regex" : token.kind === "quoted" ? "phrase" : wildcard ? "wildcard" : "term",
|
|
819
|
+
value: token.kind === "regex" || wildcard ? raw : decodeEscapes(raw, token.span, fail),
|
|
820
|
+
span: { start: start ?? token.span.start, end: token.span.end },
|
|
821
|
+
...implicit ? { implicit: true } : {}
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
if (proximity && peek().kind === "~" && node.kind === "predicate" && node.operator === "phrase") {
|
|
825
|
+
take();
|
|
826
|
+
const distance = take();
|
|
827
|
+
if (distance.kind !== "number" || !/^\d+$/u.test(distance.raw))
|
|
828
|
+
fail("query.invalid-syntax", distance.span, 'write the distance as a whole number: "a b"~3');
|
|
829
|
+
node = { ...node, slop: Number(distance.raw), span: { start: node.span.start, end: distance.span.end } };
|
|
830
|
+
}
|
|
831
|
+
if (peek().kind === "~")
|
|
832
|
+
fail("query.unsupported-operator", peek().span, node.kind === "predicate" && node.operator === "phrase" ? "proximity (~) is not supported \u2014 drop the ~ for the exact phrase, or join the words with AND" : "fuzzy matching (~) is not supported \u2014 use a prefix such as word* to catch word forms");
|
|
833
|
+
if (["^", "@"].includes(peek().kind))
|
|
834
|
+
fail("query.unsupported-operator", peek().span, "boost and minimum-should-match are not supported");
|
|
835
|
+
return { node, ...modifier ? { modifier } : {} };
|
|
836
|
+
}, "clause");
|
|
837
|
+
const root = query(defaultField, true);
|
|
838
|
+
expect("EOF");
|
|
839
|
+
if (defaultField === "none") {
|
|
840
|
+
const bare = walkQuery(root).find((node) => node.implicit);
|
|
841
|
+
if (bare)
|
|
842
|
+
queryError("query.bare-word", bare.span, `"${bare.value}" has no field; write field:value`, context3, {
|
|
843
|
+
word: bare.value
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
return { version: 1, language: "lucene-v1", root };
|
|
847
|
+
}, "parseLucene");
|
|
848
|
+
var implicitTextTerms = /* @__PURE__ */ __name((text5) => {
|
|
849
|
+
const tokens = tokensOf(text5);
|
|
850
|
+
if (tokens.some(({ kind }) => ["AND", "OR", "NOT", "+", "-", "!", "(", ")"].includes(kind)))
|
|
851
|
+
return /* @__PURE__ */ new Set();
|
|
852
|
+
return new Set(tokens.flatMap((token, index) => (token.kind === "term" || token.kind === "number") && ![":", "=", "<", ">", "<=", ">="].includes(tokens[index - 1]?.kind ?? "") && ![":", "=", "<", ">", "<=", ">="].includes(tokens[index + 1]?.kind ?? "") ? [token.span.start] : []));
|
|
853
|
+
}, "implicitTextTerms");
|
|
854
|
+
|
|
855
|
+
// node_modules/.pnpm/@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/registry.js
|
|
856
|
+
var describeQuery = /* @__PURE__ */ __name((registry) => ({
|
|
857
|
+
entity: registry.entity,
|
|
858
|
+
backend: registry.backend,
|
|
859
|
+
fields: registry.fields.map(({ validate: _, ...field }) => field),
|
|
860
|
+
...registry.defaults && registry.defaults.length > 0 ? { defaults: [...registry.defaults] } : {}
|
|
861
|
+
}), "describeQuery");
|
|
862
|
+
var exampleProblems = /* @__PURE__ */ __name((registry) => {
|
|
863
|
+
const syntaxOnly = { ...registry, backend: "sql" };
|
|
864
|
+
const problem = /* @__PURE__ */ __name((text5, field) => {
|
|
865
|
+
try {
|
|
866
|
+
const named = walkQuery(validateQuery(parseLucene(text5, { defaultField: "none" }), syntaxOnly).root);
|
|
867
|
+
return named.every((node) => node.field === field) ? void 0 : `"${text5}" does not name ${field}`;
|
|
868
|
+
} catch (failure) {
|
|
869
|
+
if (!isCliError(failure))
|
|
870
|
+
throw failure;
|
|
871
|
+
return `"${text5}": ${failure.message}`;
|
|
872
|
+
}
|
|
873
|
+
}, "problem");
|
|
874
|
+
const defaults = (registry.defaults ?? []).map((term) => {
|
|
875
|
+
const field = term.replace(/^-/, "").split(/[:<>=]/)[0] ?? "";
|
|
876
|
+
return { field, problem: problem(term.replace(/^-/, ""), field) };
|
|
877
|
+
});
|
|
878
|
+
return [
|
|
879
|
+
...registry.fields.map((field) => ({ field: field.name, problem: problem(field.example, field.name) })),
|
|
880
|
+
...defaults
|
|
881
|
+
].filter((entry) => entry.problem !== void 0);
|
|
882
|
+
}, "exampleProblems");
|
|
883
|
+
var checked = /* @__PURE__ */ new WeakSet();
|
|
884
|
+
var defineQuery = /* @__PURE__ */ __name((registry) => {
|
|
885
|
+
if (checked.has(registry))
|
|
886
|
+
return registry;
|
|
887
|
+
const names = registry.fields.map((field) => field.name);
|
|
888
|
+
const problems = [
|
|
889
|
+
...duplicates(names).map((name) => `"${name}" is listed twice`),
|
|
890
|
+
...names.filter((name) => !SNAKE_CASE.test(name)).map((name) => `"${name}" is not snake_case`),
|
|
891
|
+
...exampleProblems(registry).map(({ field, problem }) => `${field}: ${problem}`)
|
|
892
|
+
];
|
|
893
|
+
if (problems.length > 0)
|
|
894
|
+
throw new RegistryError(`${registry.entity} query`, problems);
|
|
895
|
+
checked.add(registry);
|
|
896
|
+
return registry;
|
|
897
|
+
}, "defineQuery");
|
|
898
|
+
var SPAN = ["span", "alternative", "guide"];
|
|
899
|
+
var QUERY_REASONS = defineReasons([
|
|
900
|
+
["query.bare-word", "a word in the query has no field", ["word"]],
|
|
901
|
+
["query.invalid-ast", "the query tree is not valid", []],
|
|
902
|
+
["query.invalid-date", "a date in the query cannot be read", []],
|
|
903
|
+
["query.invalid-escape", "an escape in the query is not valid", []],
|
|
904
|
+
["query.invalid-number", "a number in the query cannot be read", []],
|
|
905
|
+
["query.invalid-regex", "a regular expression in the query is not valid", []],
|
|
906
|
+
["query.invalid-syntax", "the query cannot be parsed", []],
|
|
907
|
+
["query.invalid-timezone", "the time zone is not known", []],
|
|
908
|
+
["query.missing-value", "a field in the query has no value", []],
|
|
909
|
+
["query.too-large", "the query is over one of its limits", []],
|
|
910
|
+
["query.unclosed-literal", "a quote or bracket in the query is not closed", []],
|
|
911
|
+
["query.unknown-field", "a field in the query is not known", ["fields"]],
|
|
912
|
+
["query.unknown-value", "a value in the query is not known", []],
|
|
913
|
+
["query.unsupported-field", "this list cannot filter by that field", ["supported"]],
|
|
914
|
+
["query.unsupported-operator", "this field does not take that operator", []],
|
|
915
|
+
["query.unsupported-placement", "this field works only as a required term", []],
|
|
916
|
+
["query.unsupported-regex", "that regular expression is not supported", []],
|
|
917
|
+
["query.unsupported-regex-flags", "regular expression flags are not supported", []],
|
|
918
|
+
["query.unsupported-version", "the query version is not supported", []]
|
|
919
|
+
].map(([reason, message, details]) => ({
|
|
920
|
+
reason,
|
|
921
|
+
code: "validation_error",
|
|
922
|
+
message,
|
|
923
|
+
details: [...SPAN, ...details]
|
|
924
|
+
})));
|
|
925
|
+
|
|
926
|
+
// node_modules/.pnpm/@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/evaluate.js
|
|
927
|
+
var wordsOf = /* @__PURE__ */ __name((text5) => text5.toLowerCase().match(/[\p{L}\p{N}]+/gu) ?? [], "wordsOf");
|
|
928
|
+
var pattern = /* @__PURE__ */ __name((value) => new RegExp(`^${[...value].map((char) => char === "*" ? ".*" : char === "?" ? "." : char.replace(/[.+^${}()|[\]\\]/, "\\$&")).join("")}$`, "iu"), "pattern");
|
|
929
|
+
var present = /* @__PURE__ */ __name((value) => value !== void 0 && value !== null && value !== "", "present");
|
|
930
|
+
var matchOne = /* @__PURE__ */ __name((field, node, value, options) => {
|
|
931
|
+
if (!present(value))
|
|
932
|
+
return false;
|
|
933
|
+
if (node.operator === "wildcard" && node.value === "*")
|
|
934
|
+
return true;
|
|
935
|
+
const text5 = String(value);
|
|
936
|
+
switch (field.type) {
|
|
937
|
+
case "txt": {
|
|
938
|
+
const words2 = wordsOf(text5);
|
|
939
|
+
if (node.operator === "wildcard")
|
|
940
|
+
return words2.some((word) => pattern(node.value).test(word));
|
|
941
|
+
const wanted = wordsOf(node.value);
|
|
942
|
+
return words2.some((_, at) => wanted.every((word, offset) => words2[at + offset] === word));
|
|
943
|
+
}
|
|
944
|
+
case "num": {
|
|
945
|
+
const number2 = Number(value);
|
|
946
|
+
if (node.operator !== "range")
|
|
947
|
+
return number2 === Number(node.value);
|
|
948
|
+
const { value: lower, upper = "*", lower_inclusive: lowerInclusive, upper_inclusive: upperInclusive } = node;
|
|
949
|
+
return (lower === "*" || (lowerInclusive ? number2 >= Number(lower) : number2 > Number(lower))) && (upper === "*" || (upperInclusive ? number2 <= Number(upper) : number2 < Number(upper)));
|
|
950
|
+
}
|
|
951
|
+
case "time": {
|
|
952
|
+
const time = Date.parse(text5);
|
|
953
|
+
const [lower, upper, lowerInclusive, upperInclusive] = node.operator === "range" ? [node.value, node.upper ?? "*", node.lower_inclusive ?? true, node.upper_inclusive ?? true] : [node.value, node.value, true, true];
|
|
954
|
+
const range = dateRange(lower, upper, lowerInclusive, upperInclusive, options.zone ?? "UTC", node.span, options.now);
|
|
955
|
+
return (range.lower === void 0 || (range.lower_inclusive ? time >= range.lower : time > range.lower)) && (range.upper === void 0 || (range.upper_inclusive ? time <= range.upper : time < range.upper));
|
|
956
|
+
}
|
|
957
|
+
default:
|
|
958
|
+
return node.operator === "wildcard" ? pattern(node.value).test(text5) : text5.toLowerCase() === node.value.toLowerCase();
|
|
959
|
+
}
|
|
960
|
+
}, "matchOne");
|
|
961
|
+
var matches = /* @__PURE__ */ __name((node, item, byName, options) => {
|
|
962
|
+
if (node.kind === "boolean") {
|
|
963
|
+
const by = /* @__PURE__ */ __name((occur) => node.clauses.filter((clause) => clause.occur === occur), "by");
|
|
964
|
+
const [must, should, mustNot] = [by("must"), by("should"), by("must_not")];
|
|
965
|
+
const holds = /* @__PURE__ */ __name((clause) => matches(clause.node, item, byName, options), "holds");
|
|
966
|
+
return must.every(holds) && !mustNot.some(holds) && (should.length === 0 || must.length > 0 || should.some(holds));
|
|
967
|
+
}
|
|
968
|
+
const field = byName.get(node.field);
|
|
969
|
+
if (!field)
|
|
970
|
+
throw new Error(`evaluate: no field "${node.field}"; validate the query first`);
|
|
971
|
+
if (field.relation !== void 0) {
|
|
972
|
+
if (!options.relation)
|
|
973
|
+
throw new Error(`evaluate: "${node.field}" is a relation; pass options.relation`);
|
|
974
|
+
return options.relation(node, item);
|
|
975
|
+
}
|
|
976
|
+
const value = item[node.field];
|
|
977
|
+
return Array.isArray(value) ? value.some((one) => matchOne(field, node, one, options)) : matchOne(field, node, value, options);
|
|
978
|
+
}, "matches");
|
|
979
|
+
var evaluate = /* @__PURE__ */ __name((ast, fields, item, options = {}) => matches(ast.root, item, new Map(fields.map((field) => [field.name, field])), options), "evaluate");
|
|
980
|
+
|
|
981
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/reference.js
|
|
982
|
+
var invalid = /* @__PURE__ */ __name(() => new CliError("validation_error", "expected meeting:<accountId>/<meetingId>[/<transcriptId>[/<cuePosition>]] with safe integer IDs"), "invalid");
|
|
983
|
+
var integer2 = /* @__PURE__ */ __name((value, minimum = 1) => {
|
|
984
|
+
if (!Number.isSafeInteger(value) || value < minimum)
|
|
985
|
+
throw invalid();
|
|
986
|
+
return value;
|
|
987
|
+
}, "integer");
|
|
988
|
+
var formatMeetingReference = /* @__PURE__ */ __name((reference2) => {
|
|
989
|
+
const parts = [integer2(reference2.accountId), integer2(reference2.meetingId)];
|
|
990
|
+
if (reference2.transcriptId !== void 0)
|
|
991
|
+
parts.push(integer2(reference2.transcriptId));
|
|
992
|
+
if (reference2.cuePosition !== void 0) {
|
|
993
|
+
if (reference2.transcriptId === void 0)
|
|
994
|
+
throw invalid();
|
|
995
|
+
parts.push(integer2(reference2.cuePosition, 0));
|
|
996
|
+
}
|
|
997
|
+
return `meeting:${parts.join("/")}`;
|
|
998
|
+
}, "formatMeetingReference");
|
|
999
|
+
var parseMeetingReference = /* @__PURE__ */ __name((text5) => {
|
|
1000
|
+
const value = text5.trim();
|
|
1001
|
+
if (!value.startsWith("meeting:"))
|
|
1002
|
+
throw invalid();
|
|
1003
|
+
const parts = value.slice(8).split("/");
|
|
1004
|
+
if (parts.length < 2 || parts.length > 4 || parts.some((part) => !/^\d+$/.test(part)))
|
|
1005
|
+
throw invalid();
|
|
1006
|
+
const ids2 = parts.map(Number);
|
|
1007
|
+
const reference2 = {
|
|
1008
|
+
type: "meeting",
|
|
1009
|
+
accountId: integer2(ids2[0]),
|
|
1010
|
+
meetingId: integer2(ids2[1]),
|
|
1011
|
+
...ids2.length > 2 ? { transcriptId: integer2(ids2[2]) } : {},
|
|
1012
|
+
...ids2.length > 3 ? { cuePosition: integer2(ids2[3], 0) } : {}
|
|
1013
|
+
};
|
|
1014
|
+
return reference2;
|
|
1015
|
+
}, "parseMeetingReference");
|
|
1016
|
+
var canonicalMeetingReference = /* @__PURE__ */ __name((text5) => formatMeetingReference(parseMeetingReference(text5)), "canonicalMeetingReference");
|
|
1017
|
+
|
|
1018
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/item.js
|
|
1019
|
+
var text = string();
|
|
1020
|
+
var count = pipe(number(), integer(), minValue(0));
|
|
1021
|
+
var MEETING_ISSUES = ["time_without_zone"];
|
|
1022
|
+
var meetingIssuesOf = /* @__PURE__ */ __name((metadata) => {
|
|
1023
|
+
const listed2 = metadata?.issues;
|
|
1024
|
+
return Array.isArray(listed2) ? MEETING_ISSUES.filter((issue) => listed2.includes(issue)) : [];
|
|
1025
|
+
}, "meetingIssuesOf");
|
|
1026
|
+
var meeting = strictObject({
|
|
1027
|
+
ref: reference,
|
|
1028
|
+
id: pipe(string(), minLength(1)),
|
|
1029
|
+
provider: text,
|
|
1030
|
+
account: text,
|
|
1031
|
+
title: nullable(text),
|
|
1032
|
+
description: optional(nullable(text)),
|
|
1033
|
+
location: optional(nullable(text)),
|
|
1034
|
+
/** The link that joins it. */
|
|
1035
|
+
url: nullable(text),
|
|
1036
|
+
started_at: nullable(isoTime),
|
|
1037
|
+
ended_at: nullable(isoTime),
|
|
1038
|
+
duration_ms: nullable(count),
|
|
1039
|
+
timezone: optional(nullable(text)),
|
|
1040
|
+
participants_count: nullable(count),
|
|
1041
|
+
/** Present only when something about this meeting is doubtful. */
|
|
1042
|
+
issues: optional(array(picklist(MEETING_ISSUES))),
|
|
1043
|
+
created_at: isoTime,
|
|
1044
|
+
updated_at: isoTime
|
|
1045
|
+
});
|
|
1046
|
+
var iso = /* @__PURE__ */ __name((ms) => ms === null ? null : new Date(ms).toISOString(), "iso");
|
|
1047
|
+
var meetingItem = /* @__PURE__ */ __name((row, owner) => {
|
|
1048
|
+
const issues = meetingIssuesOf(row.metadata);
|
|
1049
|
+
return {
|
|
1050
|
+
ref: formatMeetingReference({ type: "meeting", accountId: row.accountId, meetingId: row.id }),
|
|
1051
|
+
id: String(row.id),
|
|
1052
|
+
provider: owner.provider,
|
|
1053
|
+
account: owner.account,
|
|
1054
|
+
title: row.title,
|
|
1055
|
+
description: row.description,
|
|
1056
|
+
location: row.location,
|
|
1057
|
+
url: row.joinUrl,
|
|
1058
|
+
started_at: iso(row.startedAt),
|
|
1059
|
+
ended_at: iso(row.endedAt),
|
|
1060
|
+
duration_ms: row.durationMs,
|
|
1061
|
+
timezone: row.timezone,
|
|
1062
|
+
participants_count: row.participantsCount,
|
|
1063
|
+
...issues.length ? { issues } : {},
|
|
1064
|
+
created_at: new Date(row.createdAt).toISOString(),
|
|
1065
|
+
updated_at: new Date(row.updatedAt).toISOString()
|
|
1066
|
+
};
|
|
1067
|
+
}, "meetingItem");
|
|
1068
|
+
var MEETING_QUERY = {
|
|
1069
|
+
entity: "meeting",
|
|
1070
|
+
backend: "sql",
|
|
1071
|
+
fields: queryFieldsOf(meeting, {
|
|
1072
|
+
exclude: ["ref", "provider", "account", "description", "location", "url", "timezone", "issues"],
|
|
1073
|
+
examples: {
|
|
1074
|
+
id: "id:12",
|
|
1075
|
+
title: "title:*standup*",
|
|
1076
|
+
started_at: "started_at:[2026-10-01 TO 2026-10-31]",
|
|
1077
|
+
duration_ms: "duration_ms>=3600000",
|
|
1078
|
+
participants_count: "participants_count>5"
|
|
1079
|
+
}
|
|
1080
|
+
})
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/join-key.js
|
|
1084
|
+
var joinKeyOf = /* @__PURE__ */ __name((url) => {
|
|
1085
|
+
const parsed = urlOf(url);
|
|
1086
|
+
if (!parsed)
|
|
1087
|
+
return null;
|
|
1088
|
+
const host = parsed.hostname.toLowerCase().replace(/^www\./u, "");
|
|
1089
|
+
const path = parsed.pathname.replace(/\/+$/u, "");
|
|
1090
|
+
if (host === "zoom.us" || host.endsWith(".zoom.us") || host === "zoomgov.com" || host.endsWith(".zoomgov.com")) {
|
|
1091
|
+
const number2 = /^\/(?:j|w|s|wc\/join|wc)\/(\d{9,12})(?:\/|$)/u.exec(path)?.[1];
|
|
1092
|
+
if (number2)
|
|
1093
|
+
return `zoom:${number2}`;
|
|
1094
|
+
}
|
|
1095
|
+
if (host === "meet.google.com") {
|
|
1096
|
+
const code = /^\/([a-z]{3}-[a-z]{4}-[a-z]{3})$/iu.exec(path)?.[1];
|
|
1097
|
+
if (code)
|
|
1098
|
+
return `meet:${code.toLowerCase()}`;
|
|
1099
|
+
}
|
|
1100
|
+
return `${host}${path}`;
|
|
1101
|
+
}, "joinKeyOf");
|
|
1102
|
+
var joinUrlWithoutQuery = /* @__PURE__ */ __name((url) => {
|
|
1103
|
+
const parsed = urlOf(url);
|
|
1104
|
+
return parsed ? `${parsed.origin}${parsed.pathname}` : null;
|
|
1105
|
+
}, "joinUrlWithoutQuery");
|
|
1106
|
+
var urlOf = /* @__PURE__ */ __name((url) => {
|
|
1107
|
+
if (!url?.trim())
|
|
1108
|
+
return null;
|
|
1109
|
+
try {
|
|
1110
|
+
const parsed = new URL(url.trim());
|
|
1111
|
+
return parsed.protocol === "https:" || parsed.protocol === "http:" ? parsed : null;
|
|
1112
|
+
} catch {
|
|
1113
|
+
return null;
|
|
1114
|
+
}
|
|
1115
|
+
}, "urlOf");
|
|
1116
|
+
|
|
1117
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/calendar-text.js
|
|
1118
|
+
var ENTITIES = { amp: "&", lt: "<", gt: ">", quot: '"', "#39": "'", apos: "'", nbsp: " " };
|
|
1119
|
+
var SECRET_LINE = /(?<![\p{L}\p{N}])(pass ?codes?|passwords?|pwd|pins?|access ?codes?|meeting ?codes?|kennwort|пароль|пин-?код|код доступа)(?![\p{L}\p{N}])|pwd=/iu;
|
|
1120
|
+
var htmlToText = /* @__PURE__ */ __name((html) => html.replace(/<\s*br\s*\/?>/giu, "\n").replace(/<\/\s*(p|div|li|tr|h[1-6])\s*>/giu, "\n").replace(/<a\s[^>]*href\s*=\s*"([^"]*)"[^>]*>/giu, " $1 ").replace(/<[^>]+>/gu, "").replace(/&(amp|lt|gt|quot|#39|apos|nbsp);/gu, (_, name) => ENTITIES[name] ?? ""), "htmlToText");
|
|
1121
|
+
var withoutLinkQueries = /* @__PURE__ */ __name((text5) => text5.replace(/https?:\/\/[^\s<>"')\]]+/giu, (url) => joinUrlWithoutQuery(url) ?? ""), "withoutLinkQueries");
|
|
1122
|
+
var calendarText = /* @__PURE__ */ __name((text5, { dropSecretLines = true } = {}) => {
|
|
1123
|
+
if (!text5)
|
|
1124
|
+
return null;
|
|
1125
|
+
const kept = htmlToText(text5).split(/\r?\n/u).map((line2) => withoutLinkQueries(line2).replace(/[ \t]+/gu, " ").trim()).filter((line2) => !dropSecretLines || !SECRET_LINE.test(line2));
|
|
1126
|
+
const joined = kept.join("\n").replace(/\n{3,}/gu, "\n\n").trim();
|
|
1127
|
+
return joined || null;
|
|
1128
|
+
}, "calendarText");
|
|
1129
|
+
var ENTRY_METADATA_KEYS = [
|
|
1130
|
+
"colorId",
|
|
1131
|
+
"guestsCanInviteOthers",
|
|
1132
|
+
"guestsCanModify",
|
|
1133
|
+
"guestsCanSeeOtherGuests",
|
|
1134
|
+
"hangoutLink",
|
|
1135
|
+
"locked",
|
|
1136
|
+
"privateCopy"
|
|
1137
|
+
];
|
|
1138
|
+
var entryMetadata = /* @__PURE__ */ __name((metadata) => {
|
|
1139
|
+
const kept = {};
|
|
1140
|
+
for (const key of ENTRY_METADATA_KEYS) {
|
|
1141
|
+
const value = metadata?.[key];
|
|
1142
|
+
if (typeof value === "string")
|
|
1143
|
+
kept[key] = withoutLinkQueries(value);
|
|
1144
|
+
else if (typeof value === "number" || typeof value === "boolean")
|
|
1145
|
+
kept[key] = value;
|
|
1146
|
+
}
|
|
1147
|
+
return kept;
|
|
1148
|
+
}, "entryMetadata");
|
|
1149
|
+
|
|
1150
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/cue-fingerprint.js
|
|
1151
|
+
import { createHash } from "node:crypto";
|
|
1152
|
+
var meetingCueFingerprint = /* @__PURE__ */ __name((cue2) => createHash("sha256").update(JSON.stringify({
|
|
1153
|
+
reference: cue2.reference,
|
|
1154
|
+
transcriptId: cue2.transcriptId,
|
|
1155
|
+
contentHash: cue2.contentHash,
|
|
1156
|
+
position: cue2.position,
|
|
1157
|
+
startMs: cue2.startMs,
|
|
1158
|
+
endMs: cue2.endMs,
|
|
1159
|
+
speakerParticipantId: cue2.speakerParticipantId,
|
|
1160
|
+
speakerName: cue2.speakerName,
|
|
1161
|
+
text: cue2.text
|
|
1162
|
+
})).digest("hex"), "meetingCueFingerprint");
|
|
1163
|
+
|
|
1164
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/event-store.js
|
|
1165
|
+
var UNTIL = /(?:^|;)UNTIL=(\d{4})(\d{2})(\d{2})(?:T(\d{2})(\d{2})(\d{2})Z?)?(?:;|$)/iu;
|
|
1166
|
+
var seriesEnd = /* @__PURE__ */ __name((entry) => {
|
|
1167
|
+
if (entry.recurrenceEndsAt !== null)
|
|
1168
|
+
return entry.recurrenceEndsAt;
|
|
1169
|
+
const rule = entry.recurrence?.find((line2) => /^RRULE:/iu.test(line2));
|
|
1170
|
+
const until = rule === void 0 ? null : UNTIL.exec(rule.slice("RRULE:".length));
|
|
1171
|
+
if (!until)
|
|
1172
|
+
return Number.POSITIVE_INFINITY;
|
|
1173
|
+
const [, year, month, day, hour = "23", minute = "59", second = "59"] = until;
|
|
1174
|
+
return Date.UTC(Number(year), Number(month) - 1, Number(day), Number(hour), Number(minute), Number(second)) + 864e5;
|
|
1175
|
+
}, "seriesEnd");
|
|
1176
|
+
var entryInWindow = /* @__PURE__ */ __name((entry, window) => {
|
|
1177
|
+
if (entry.kind === "occurrence" && !entry.exception)
|
|
1178
|
+
return entry.originalStartsAt !== null && entry.originalStartsAt >= window.from && entry.originalStartsAt < window.to;
|
|
1179
|
+
const start = entry.startsAt ?? (entry.kind === "occurrence" ? entry.originalStartsAt : null);
|
|
1180
|
+
if (start === null || start >= window.to)
|
|
1181
|
+
return false;
|
|
1182
|
+
if (entry.kind === "series")
|
|
1183
|
+
return seriesEnd(entry) >= window.from;
|
|
1184
|
+
return Math.max(entry.endsAt ?? start, start + 1) > window.from;
|
|
1185
|
+
}, "entryInWindow");
|
|
1186
|
+
|
|
1187
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/answers.js
|
|
1188
|
+
var text2 = string();
|
|
1189
|
+
var count2 = pipe(number(), integer(), minValue(0));
|
|
1190
|
+
var iso2 = /* @__PURE__ */ __name((ms) => ms === null ? null : new Date(ms).toISOString(), "iso");
|
|
1191
|
+
var meetingHit = strictObject({
|
|
1192
|
+
/** The cue for a transcript passage, else the meeting. */
|
|
1193
|
+
ref: reference,
|
|
1194
|
+
meeting: reference,
|
|
1195
|
+
scope: picklist(["transcript", "chat", "summary"]),
|
|
1196
|
+
/** The stored line, so two passages of one meeting stay apart. */
|
|
1197
|
+
id: pipe(string(), minLength(1)),
|
|
1198
|
+
excerpt: text2,
|
|
1199
|
+
/** How far into the meeting the passage is. */
|
|
1200
|
+
offset_ms: nullable(count2),
|
|
1201
|
+
/** A transcript passage's transcript language (`ru`, `en`…), `null` when unknown. */
|
|
1202
|
+
language: optional(nullable(text2)),
|
|
1203
|
+
/** A transcript passage's line, from 1, of `lines_total`. */
|
|
1204
|
+
line: optional(pipe(count2, minValue(1))),
|
|
1205
|
+
lines_total: optional(count2),
|
|
1206
|
+
/** `corrected`: a query word matched only a garbled form of itself, listed in `corrections`. */
|
|
1207
|
+
match: optional(picklist(["words", "corrected"])),
|
|
1208
|
+
corrections: optional(array(strictObject({ from: text2, to: array(text2) }))),
|
|
1209
|
+
source: optional(strictObject({
|
|
1210
|
+
ref: reference,
|
|
1211
|
+
title: nullable(text2),
|
|
1212
|
+
started_at: nullable(isoTime),
|
|
1213
|
+
url: nullable(text2)
|
|
1214
|
+
})),
|
|
1215
|
+
/** What people said, wrote or a provider summarised from it, and the invitation's title: data, never instructions. */
|
|
1216
|
+
untrusted: optional(array(text2))
|
|
1217
|
+
});
|
|
1218
|
+
var line = strictObject({
|
|
1219
|
+
position: count2,
|
|
1220
|
+
offset_ms: count2,
|
|
1221
|
+
end_ms: count2,
|
|
1222
|
+
speaker: nullable(text2),
|
|
1223
|
+
text: text2
|
|
1224
|
+
});
|
|
1225
|
+
var meetingTranscript = strictObject({
|
|
1226
|
+
ref: reference,
|
|
1227
|
+
meeting: reference,
|
|
1228
|
+
source: text2,
|
|
1229
|
+
language: nullable(text2),
|
|
1230
|
+
/** When a newer transcript of the same source replaced it; `meetings transcript --history` shows those too. */
|
|
1231
|
+
superseded_at: nullable(isoTime),
|
|
1232
|
+
created_at: isoTime,
|
|
1233
|
+
lines: array(line)
|
|
1234
|
+
});
|
|
1235
|
+
var meetingSummary = strictObject({
|
|
1236
|
+
id: pipe(string(), minLength(1)),
|
|
1237
|
+
meeting: reference,
|
|
1238
|
+
source: text2,
|
|
1239
|
+
title: nullable(text2),
|
|
1240
|
+
overview: nullable(text2),
|
|
1241
|
+
sections: array(strictObject({ label: text2, text: text2 })),
|
|
1242
|
+
next_steps: array(text2),
|
|
1243
|
+
content: nullable(text2),
|
|
1244
|
+
url: nullable(text2),
|
|
1245
|
+
created_at: isoTime,
|
|
1246
|
+
updated_at: isoTime
|
|
1247
|
+
});
|
|
1248
|
+
var meetingDetails = strictObject({
|
|
1249
|
+
...meeting.entries,
|
|
1250
|
+
/** The stored event and series it belongs to, as `meetings_list` takes them. */
|
|
1251
|
+
event_id: nullable(text2),
|
|
1252
|
+
series_id: nullable(text2),
|
|
1253
|
+
series_title: nullable(text2),
|
|
1254
|
+
participants: array(strictObject({
|
|
1255
|
+
name: nullable(text2),
|
|
1256
|
+
email: nullable(text2),
|
|
1257
|
+
role: nullable(text2),
|
|
1258
|
+
joined_at: nullable(isoTime),
|
|
1259
|
+
left_at: nullable(isoTime),
|
|
1260
|
+
duration_ms: nullable(count2)
|
|
1261
|
+
})),
|
|
1262
|
+
transcripts: array(strictObject({ ref: reference, source: text2, language: nullable(text2), lines_count: count2 })),
|
|
1263
|
+
chat: array(strictObject({ sent_at: isoTime, sender: nullable(text2), recipient: nullable(text2), text: text2 })),
|
|
1264
|
+
summaries: array(meetingSummary),
|
|
1265
|
+
attachments: array(strictObject({
|
|
1266
|
+
position: count2,
|
|
1267
|
+
kind: text2,
|
|
1268
|
+
name: nullable(text2),
|
|
1269
|
+
mime: nullable(text2),
|
|
1270
|
+
size: nullable(count2),
|
|
1271
|
+
url: nullable(text2)
|
|
1272
|
+
}))
|
|
1273
|
+
});
|
|
1274
|
+
var meetingRef = /* @__PURE__ */ __name((accountId, meetingId) => formatMeetingReference({ type: "meeting", accountId, meetingId }), "meetingRef");
|
|
1275
|
+
var meetingTranscriptItem = /* @__PURE__ */ __name((accountId, transcript, rows) => ({
|
|
1276
|
+
ref: formatMeetingReference({
|
|
1277
|
+
type: "meeting",
|
|
1278
|
+
accountId,
|
|
1279
|
+
meetingId: transcript.meetingId,
|
|
1280
|
+
transcriptId: transcript.id
|
|
1281
|
+
}),
|
|
1282
|
+
meeting: meetingRef(accountId, transcript.meetingId),
|
|
1283
|
+
source: transcript.source,
|
|
1284
|
+
language: transcript.language,
|
|
1285
|
+
superseded_at: iso2(transcript.supersededAt),
|
|
1286
|
+
created_at: new Date(transcript.externalCreatedAt ?? transcript.createdAt).toISOString(),
|
|
1287
|
+
lines: rows.map((row) => ({
|
|
1288
|
+
position: row.position,
|
|
1289
|
+
offset_ms: row.startMs,
|
|
1290
|
+
end_ms: row.endMs,
|
|
1291
|
+
speaker: row.speakerName,
|
|
1292
|
+
text: row.text
|
|
1293
|
+
}))
|
|
1294
|
+
}), "meetingTranscriptItem");
|
|
1295
|
+
var meetingSummaryItem = /* @__PURE__ */ __name((accountId, summary) => ({
|
|
1296
|
+
id: String(summary.id),
|
|
1297
|
+
meeting: meetingRef(accountId, summary.meetingId),
|
|
1298
|
+
source: summary.source,
|
|
1299
|
+
title: summary.title,
|
|
1300
|
+
overview: summary.overview,
|
|
1301
|
+
sections: summary.sections.map(({ label, text: text5 }) => ({ label, text: text5 })),
|
|
1302
|
+
next_steps: summary.nextSteps,
|
|
1303
|
+
content: summary.content,
|
|
1304
|
+
url: summary.docUrl,
|
|
1305
|
+
created_at: new Date(summary.externalCreatedAt ?? summary.createdAt).toISOString(),
|
|
1306
|
+
updated_at: new Date(summary.externalUpdatedAt ?? summary.updatedAt).toISOString()
|
|
1307
|
+
}), "meetingSummaryItem");
|
|
1308
|
+
var meetingDetailsItem = /* @__PURE__ */ __name((details, owner) => {
|
|
1309
|
+
const { accountId } = details.meeting;
|
|
1310
|
+
return {
|
|
1311
|
+
...meetingItem(details.meeting, owner),
|
|
1312
|
+
event_id: details.meeting.eventId === null ? null : String(details.meeting.eventId),
|
|
1313
|
+
series_id: details.meeting.meetingSeriesId === null ? null : String(details.meeting.meetingSeriesId),
|
|
1314
|
+
series_title: details.series?.title ?? null,
|
|
1315
|
+
participants: details.participants.map((one) => ({
|
|
1316
|
+
name: one.displayName,
|
|
1317
|
+
email: one.email,
|
|
1318
|
+
role: one.role,
|
|
1319
|
+
joined_at: iso2(one.joinedAt),
|
|
1320
|
+
left_at: iso2(one.leftAt),
|
|
1321
|
+
duration_ms: one.durationMs
|
|
1322
|
+
})),
|
|
1323
|
+
transcripts: details.transcripts.filter(({ transcript }) => transcript.supersededAt === null && transcript.deletedAt === null).map(({ transcript, rows }) => ({
|
|
1324
|
+
ref: formatMeetingReference({
|
|
1325
|
+
type: "meeting",
|
|
1326
|
+
accountId,
|
|
1327
|
+
meetingId: transcript.meetingId,
|
|
1328
|
+
transcriptId: transcript.id
|
|
1329
|
+
}),
|
|
1330
|
+
source: transcript.source,
|
|
1331
|
+
language: transcript.language,
|
|
1332
|
+
lines_count: rows.length
|
|
1333
|
+
})),
|
|
1334
|
+
chat: details.chat.map((one) => ({
|
|
1335
|
+
sent_at: new Date(one.sentAt).toISOString(),
|
|
1336
|
+
sender: one.senderName,
|
|
1337
|
+
recipient: one.recipient,
|
|
1338
|
+
text: one.text
|
|
1339
|
+
})),
|
|
1340
|
+
summaries: details.summaries.map((one) => meetingSummaryItem(accountId, one)),
|
|
1341
|
+
attachments: details.attachments.map((one) => ({
|
|
1342
|
+
position: one.position,
|
|
1343
|
+
kind: one.kind,
|
|
1344
|
+
name: one.name ?? one.title,
|
|
1345
|
+
mime: one.mime,
|
|
1346
|
+
size: one.size,
|
|
1347
|
+
url: one.url
|
|
1348
|
+
}))
|
|
1349
|
+
};
|
|
1350
|
+
}, "meetingDetailsItem");
|
|
1351
|
+
var wholeList = /* @__PURE__ */ __name((items) => ({
|
|
1352
|
+
items,
|
|
1353
|
+
page: { mode: "page", limit: Math.max(1, items.length), has_more: false }
|
|
1354
|
+
}), "wholeList");
|
|
1355
|
+
var PAGE_NEXT = STEPS.find((step) => step.id === "page.next");
|
|
1356
|
+
var MEETING_STEPS = defineSteps([
|
|
1357
|
+
{
|
|
1358
|
+
id: "meetings.search-again",
|
|
1359
|
+
command: "*",
|
|
1360
|
+
args: [],
|
|
1361
|
+
why: "passages that changed since they were indexed were left out; the next search indexes them first"
|
|
1362
|
+
}
|
|
1363
|
+
]);
|
|
1364
|
+
var SEARCH_AGAIN = MEETING_STEPS[0];
|
|
1365
|
+
var meetingHitItem = /* @__PURE__ */ __name((hit) => ({
|
|
1366
|
+
ref: hit.ref,
|
|
1367
|
+
meeting: meetingRef(parseMeetingReference(hit.ref).accountId, hit.meetingId),
|
|
1368
|
+
scope: hit.scope,
|
|
1369
|
+
id: String(hit.id),
|
|
1370
|
+
excerpt: hit.text,
|
|
1371
|
+
offset_ms: hit.startMs,
|
|
1372
|
+
...hit.language === void 0 ? {} : { language: hit.language },
|
|
1373
|
+
...hit.line === void 0 ? {} : { line: hit.line },
|
|
1374
|
+
...hit.linesTotal === void 0 ? {} : { lines_total: hit.linesTotal },
|
|
1375
|
+
untrusted: hit.source === void 0 ? ["excerpt"] : ["excerpt", "source.title"],
|
|
1376
|
+
...hit.match === void 0 ? {} : { match: hit.match },
|
|
1377
|
+
...hit.corrections === void 0 ? {} : { corrections: hit.corrections },
|
|
1378
|
+
...hit.source === void 0 ? {} : {
|
|
1379
|
+
source: {
|
|
1380
|
+
ref: hit.ref,
|
|
1381
|
+
title: hit.source.title,
|
|
1382
|
+
started_at: iso2(hit.source.startedAt),
|
|
1383
|
+
url: hit.source.url
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
}), "meetingHitItem");
|
|
1387
|
+
var meetingHitsList = /* @__PURE__ */ __name((found, limit, command = "search meetings", args = {}, meta = {}) => {
|
|
1388
|
+
const items = found.items.map(meetingHitItem);
|
|
1389
|
+
const cursor = found.hasMore && found.nextCursor !== null ? found.nextCursor : void 0;
|
|
1390
|
+
const pending = found.coverage.indexing === "pending";
|
|
1391
|
+
const next = [
|
|
1392
|
+
...cursor === void 0 ? [] : [stepOf(PAGE_NEXT, { command, args: { ...args, cursor, limit }, values: { shown: items.length } })],
|
|
1393
|
+
...pending ? [
|
|
1394
|
+
stepOf(SEARCH_AGAIN, {
|
|
1395
|
+
command,
|
|
1396
|
+
args: Object.fromEntries(Object.entries(args).filter(([key]) => key !== "cursor"))
|
|
1397
|
+
})
|
|
1398
|
+
] : []
|
|
1399
|
+
];
|
|
1400
|
+
return {
|
|
1401
|
+
items,
|
|
1402
|
+
page: {
|
|
1403
|
+
mode: "cursor",
|
|
1404
|
+
limit,
|
|
1405
|
+
has_more: cursor !== void 0,
|
|
1406
|
+
...cursor === void 0 ? {} : { next_cursor: cursor }
|
|
1407
|
+
},
|
|
1408
|
+
...next.length > 0 ? { next } : {},
|
|
1409
|
+
...pending ? {
|
|
1410
|
+
missing: [
|
|
1411
|
+
{
|
|
1412
|
+
field: "excerpt",
|
|
1413
|
+
why: "passages that changed since they were indexed were left out",
|
|
1414
|
+
step: "meetings.search-again"
|
|
1415
|
+
}
|
|
1416
|
+
]
|
|
1417
|
+
} : {},
|
|
1418
|
+
...Object.keys(meta).length === 0 ? {} : { meta }
|
|
1419
|
+
};
|
|
1420
|
+
}, "meetingHitsList");
|
|
1421
|
+
|
|
1422
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/participant-search.js
|
|
1423
|
+
var normalizeMeetingParticipantQuery = /* @__PURE__ */ __name((text5) => text5.normalize("NFKC").toLowerCase(), "normalizeMeetingParticipantQuery");
|
|
1424
|
+
var validateMeetingParticipantQuery = /* @__PURE__ */ __name((query) => {
|
|
1425
|
+
if (typeof query !== "string" || !query.trim() || query.length > 500 || query.includes("\0"))
|
|
1426
|
+
throw new CliError("validation_error", "participant query must contain 1\u2013500 characters without NUL");
|
|
1427
|
+
return normalizeMeetingParticipantQuery(query.trim());
|
|
1428
|
+
}, "validateMeetingParticipantQuery");
|
|
1429
|
+
var validateMeetingParticipantSearch = /* @__PURE__ */ __name((query, input) => {
|
|
1430
|
+
input.signal?.throwIfAborted();
|
|
1431
|
+
const normalized = validateMeetingParticipantQuery(query);
|
|
1432
|
+
const bounded = /* @__PURE__ */ __name((value, maximum, name) => {
|
|
1433
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > maximum)
|
|
1434
|
+
throw new CliError("validation_error", `${name} must be an integer from 1 through ${maximum}`);
|
|
1435
|
+
return value;
|
|
1436
|
+
}, "bounded");
|
|
1437
|
+
return {
|
|
1438
|
+
query: normalized,
|
|
1439
|
+
accountId: bounded(input.accountId, Number.MAX_SAFE_INTEGER, "accountId"),
|
|
1440
|
+
limit: bounded(input.limit ?? 50, 1e3, "limit"),
|
|
1441
|
+
scanLimit: bounded(input.scanLimit ?? 1e3, 1e4, "scanLimit"),
|
|
1442
|
+
maxReadBytes: bounded(input.maxReadBytes ?? 1024 ** 2, 64 * 1024 ** 2, "maxReadBytes")
|
|
1443
|
+
};
|
|
1444
|
+
}, "validateMeetingParticipantSearch");
|
|
1445
|
+
|
|
1446
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/reads.js
|
|
1447
|
+
var MeetingError = class extends CliError {
|
|
1448
|
+
static {
|
|
1449
|
+
__name(this, "MeetingError");
|
|
1450
|
+
}
|
|
1451
|
+
constructor(code, message) {
|
|
1452
|
+
super(code, message);
|
|
1453
|
+
}
|
|
1454
|
+
};
|
|
1455
|
+
var positiveInteger = /* @__PURE__ */ __name((value) => {
|
|
1456
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0)
|
|
1457
|
+
throw new MeetingError("validation_error", "expected a positive integer");
|
|
1458
|
+
return value;
|
|
1459
|
+
}, "positiveInteger");
|
|
1460
|
+
var validateFilter = /* @__PURE__ */ __name((filter) => {
|
|
1461
|
+
for (const value of [filter.accountId, filter.eventId, filter.meetingSeriesId])
|
|
1462
|
+
if (value !== void 0)
|
|
1463
|
+
positiveInteger(value);
|
|
1464
|
+
for (const value of [filter.since, filter.until])
|
|
1465
|
+
if (value !== void 0 && !Number.isFinite(value))
|
|
1466
|
+
throw new MeetingError("validation_error", "expected epoch milliseconds");
|
|
1467
|
+
if (filter.since !== void 0 && filter.until !== void 0 && filter.since > filter.until)
|
|
1468
|
+
throw new MeetingError("validation_error", "since must not exceed until");
|
|
1469
|
+
for (const value of [filter.limit, filter.offset])
|
|
1470
|
+
if (value !== void 0 && (!Number.isSafeInteger(value) || value < 0))
|
|
1471
|
+
throw new MeetingError("validation_error", "expected a nonnegative integer");
|
|
1472
|
+
}, "validateFilter");
|
|
1473
|
+
var meetingShow = /* @__PURE__ */ __name(async (store, id3, accountId) => {
|
|
1474
|
+
const details = await store.meeting(positiveInteger(id3));
|
|
1475
|
+
if (!details || accountId !== void 0 && details.meeting.accountId !== accountId)
|
|
1476
|
+
throw new MeetingError("not_found", "meeting not found");
|
|
1477
|
+
return details;
|
|
1478
|
+
}, "meetingShow");
|
|
1479
|
+
var listed = /* @__PURE__ */ __name((items, page = { limit: items.length, hasMore: false }) => ({
|
|
1480
|
+
items,
|
|
1481
|
+
page: 1,
|
|
1482
|
+
...page
|
|
1483
|
+
}), "listed");
|
|
1484
|
+
var meetingPeople = /* @__PURE__ */ __name(async (store, query, accountId, options = {}) => {
|
|
1485
|
+
if (accountId === void 0)
|
|
1486
|
+
validateMeetingParticipantQuery(query);
|
|
1487
|
+
else
|
|
1488
|
+
validateMeetingParticipantSearch(query, { ...options, accountId });
|
|
1489
|
+
if (store.participantCandidates && accountId === void 0)
|
|
1490
|
+
throw new MeetingError("configuration_error", "select an account for bounded participant lookup");
|
|
1491
|
+
if (accountId !== void 0 && store.participantCandidates) {
|
|
1492
|
+
const { limit, has_more, next_cursor, ...packet } = await store.participantCandidates(query, {
|
|
1493
|
+
...options,
|
|
1494
|
+
accountId
|
|
1495
|
+
});
|
|
1496
|
+
return {
|
|
1497
|
+
...packet,
|
|
1498
|
+
page: { mode: "cursor", limit, has_more, ...next_cursor ? { next_cursor } : {} },
|
|
1499
|
+
...next_cursor ? {
|
|
1500
|
+
next: [
|
|
1501
|
+
stepOf(PAGE_NEXT2, {
|
|
1502
|
+
command: "meetings people",
|
|
1503
|
+
args: {
|
|
1504
|
+
query,
|
|
1505
|
+
limit,
|
|
1506
|
+
...options.scanLimit === void 0 ? {} : { scan_limit: options.scanLimit },
|
|
1507
|
+
...options.maxReadBytes === void 0 ? {} : { max_read_bytes: options.maxReadBytes },
|
|
1508
|
+
cursor: next_cursor
|
|
1509
|
+
},
|
|
1510
|
+
values: { shown: packet.items.length }
|
|
1511
|
+
})
|
|
1512
|
+
]
|
|
1513
|
+
} : {}
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1516
|
+
if (Object.values(options).some((value) => value !== void 0))
|
|
1517
|
+
throw new MeetingError("configuration_error", "bounded participant lookup needs a selected account and capable store");
|
|
1518
|
+
return listed(await store.participants(query, accountId));
|
|
1519
|
+
}, "meetingPeople");
|
|
1520
|
+
var PAGE_NEXT2 = STEPS.find((step) => step.id === "page.next");
|
|
1521
|
+
var meetingsList = /* @__PURE__ */ __name(async (store, filter = {}, page = 1) => {
|
|
1522
|
+
validateFilter(filter);
|
|
1523
|
+
positiveInteger(page);
|
|
1524
|
+
const limit = positiveInteger(filter.limit ?? 100);
|
|
1525
|
+
const offset = (page - 1) * limit;
|
|
1526
|
+
if (!Number.isSafeInteger(offset + limit + 1))
|
|
1527
|
+
throw new MeetingError("validation_error", "pagination exceeds safe integer range");
|
|
1528
|
+
const rows = await store.meetings({ ...filter, limit: limit + 1, offset });
|
|
1529
|
+
const shown = rows.slice(0, limit);
|
|
1530
|
+
const owners = /* @__PURE__ */ new Map();
|
|
1531
|
+
for (const { accountId } of shown) {
|
|
1532
|
+
if (owners.has(accountId))
|
|
1533
|
+
continue;
|
|
1534
|
+
const owner = await store.account(accountId);
|
|
1535
|
+
if (!owner)
|
|
1536
|
+
throw new MeetingError("not_found", `meeting account ${accountId} is not in the store`);
|
|
1537
|
+
owners.set(accountId, owner);
|
|
1538
|
+
}
|
|
1539
|
+
const has_more = rows.length > limit;
|
|
1540
|
+
return {
|
|
1541
|
+
items: shown.map((row) => meetingItem(row, owners.get(row.accountId))),
|
|
1542
|
+
page: { mode: "page", limit, has_more, ...has_more ? { next_page: page + 1 } : {} },
|
|
1543
|
+
...has_more ? {
|
|
1544
|
+
next: [
|
|
1545
|
+
stepOf(PAGE_NEXT2, { command: "meetings list", args: { page: page + 1, limit }, values: { shown: limit } })
|
|
1546
|
+
]
|
|
1547
|
+
} : {}
|
|
1548
|
+
};
|
|
1549
|
+
}, "meetingsList");
|
|
1550
|
+
var meetingsQuery = /* @__PURE__ */ __name((text5) => {
|
|
1551
|
+
if (text5 === void 0 || text5.trim() === "")
|
|
1552
|
+
return void 0;
|
|
1553
|
+
const context3 = { command: "meetings list", guide: MEETING_QUERY_GUIDE };
|
|
1554
|
+
const query = parseLucene(text5, { defaultField: "none", ...context3 });
|
|
1555
|
+
validateQuery(query, MEETING_QUERY, context3);
|
|
1556
|
+
return query;
|
|
1557
|
+
}, "meetingsQuery");
|
|
1558
|
+
var MEETING_QUERY_GUIDE = "https://github.com/WireCatLabs/cli-core/blob/main/docs/search/query-language.md";
|
|
1559
|
+
var ownerOf = /* @__PURE__ */ __name(async (store, accountId) => {
|
|
1560
|
+
const owner = await store.account(accountId);
|
|
1561
|
+
if (!owner)
|
|
1562
|
+
throw new MeetingError("not_found", `meeting account ${accountId} is not in the store`);
|
|
1563
|
+
return owner;
|
|
1564
|
+
}, "ownerOf");
|
|
1565
|
+
var meetingDetailsAnswer = /* @__PURE__ */ __name(async (store, id3, accountId) => {
|
|
1566
|
+
const details = await meetingShow(store, id3, accountId);
|
|
1567
|
+
return { item: meetingDetailsItem(details, await ownerOf(store, details.meeting.accountId)) };
|
|
1568
|
+
}, "meetingDetailsAnswer");
|
|
1569
|
+
var meetingTranscriptAnswer = /* @__PURE__ */ __name(async (store, id3, accountId, options = {}) => {
|
|
1570
|
+
const details = await meetingShow(store, id3, accountId);
|
|
1571
|
+
return wholeList(details.transcripts.filter((t) => (options.history || t.transcript.supersededAt === null) && t.transcript.deletedAt === null).map((t) => meetingTranscriptItem(details.meeting.accountId, t.transcript, t.rows)));
|
|
1572
|
+
}, "meetingTranscriptAnswer");
|
|
1573
|
+
var meetingSummaryAnswer = /* @__PURE__ */ __name(async (store, id3, accountId) => {
|
|
1574
|
+
const details = await meetingShow(store, id3, accountId);
|
|
1575
|
+
return wholeList(details.summaries.map((one) => meetingSummaryItem(details.meeting.accountId, one)));
|
|
1576
|
+
}, "meetingSummaryAnswer");
|
|
1577
|
+
|
|
1578
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/export.js
|
|
1579
|
+
var timestamp = /* @__PURE__ */ __name((milliseconds) => {
|
|
1580
|
+
if (!Number.isSafeInteger(milliseconds) || milliseconds < 0)
|
|
1581
|
+
throw new MeetingError("validation_error", "transcript times must be nonnegative integer milliseconds");
|
|
1582
|
+
const hours = Math.floor(milliseconds / 36e5);
|
|
1583
|
+
const minutes = Math.floor(milliseconds % 36e5 / 6e4);
|
|
1584
|
+
const seconds = Math.floor(milliseconds % 6e4 / 1e3);
|
|
1585
|
+
return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}.${String(milliseconds % 1e3).padStart(3, "0")}`;
|
|
1586
|
+
}, "timestamp");
|
|
1587
|
+
var vttText = /* @__PURE__ */ __name((text5) => {
|
|
1588
|
+
if (visibleControls(text5) !== text5 || /\n\s*\n/.test(text5))
|
|
1589
|
+
throw new MeetingError("validation_error", "cue paragraphs or control characters require Markdown export");
|
|
1590
|
+
return text5.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
1591
|
+
}, "vttText");
|
|
1592
|
+
var serializeVtt = /* @__PURE__ */ __name((lines) => `WEBVTT
|
|
1593
|
+
|
|
1594
|
+
${lines.map((line2, index) => {
|
|
1595
|
+
if (index > 0 && line2.startMs < (lines[index - 1]?.startMs ?? 0))
|
|
1596
|
+
throw new MeetingError("validation_error", "WebVTT cues must have nondecreasing start times");
|
|
1597
|
+
if (line2.endMs <= line2.startMs)
|
|
1598
|
+
throw new MeetingError("validation_error", "a transcript cue ends before it starts");
|
|
1599
|
+
const speaker = line2.speaker === null ? "" : `${vttText(line2.speaker)}: `;
|
|
1600
|
+
if (line2.speaker?.includes("\n"))
|
|
1601
|
+
throw new MeetingError("validation_error", "a speaker must fit on one line");
|
|
1602
|
+
return `${index + 1}
|
|
1603
|
+
${timestamp(line2.startMs)} --> ${timestamp(line2.endMs)}
|
|
1604
|
+
${speaker}${vttText(line2.text)}
|
|
1605
|
+
|
|
1606
|
+
`;
|
|
1607
|
+
}).join("")}`, "serializeVtt");
|
|
1608
|
+
var markdown = /* @__PURE__ */ __name((text5) => visibleControls(text5).replace(/[\\`*_{}[\]()<>#+.!|~]/g, "\\$&"), "markdown");
|
|
1609
|
+
var heading = /* @__PURE__ */ __name((text5) => markdown(singleLine(text5)), "heading");
|
|
1610
|
+
var quote = /* @__PURE__ */ __name((text5) => markdown(text5).split(/\r\n|\r|\n/).map((line2) => `> ${line2}`).join("\n"), "quote");
|
|
1611
|
+
var transcriptsOf = /* @__PURE__ */ __name((details, transcriptId) => {
|
|
1612
|
+
if (transcriptId !== void 0) {
|
|
1613
|
+
positiveInteger(transcriptId);
|
|
1614
|
+
const transcript = details.transcripts.find((part) => part.transcript.id === transcriptId && part.transcript.deletedAt === null);
|
|
1615
|
+
if (!transcript)
|
|
1616
|
+
throw new MeetingError("not_found", "transcript not found in the selected meeting");
|
|
1617
|
+
return [transcript];
|
|
1618
|
+
}
|
|
1619
|
+
return details.transcripts.filter((part) => part.transcript.supersededAt === null && part.transcript.deletedAt === null);
|
|
1620
|
+
}, "transcriptsOf");
|
|
1621
|
+
var exportMeeting = /* @__PURE__ */ __name(async (store, id3, options) => {
|
|
1622
|
+
if (options.format !== "markdown" && options.format !== "vtt")
|
|
1623
|
+
throw new MeetingError("validation_error", "export format must be markdown or vtt");
|
|
1624
|
+
const details = await meetingShow(store, id3, options.accountId);
|
|
1625
|
+
const transcripts = transcriptsOf(details, options.transcriptId);
|
|
1626
|
+
let content;
|
|
1627
|
+
if (options.format === "vtt") {
|
|
1628
|
+
const [selected] = transcripts;
|
|
1629
|
+
if (!selected)
|
|
1630
|
+
throw new MeetingError("not_found", "meeting has no transcript to export");
|
|
1631
|
+
if (transcripts.length > 1)
|
|
1632
|
+
throw new MeetingError("validation_error", "choose a transcript id when exporting multiple transcripts as VTT");
|
|
1633
|
+
content = serializeVtt([...selected.rows].sort((a, b) => a.position - b.position).map((row) => ({
|
|
1634
|
+
startMs: row.startMs,
|
|
1635
|
+
endMs: row.endMs,
|
|
1636
|
+
speaker: row.speakerName,
|
|
1637
|
+
text: row.text
|
|
1638
|
+
})));
|
|
1639
|
+
} else {
|
|
1640
|
+
const parts = [`# ${heading(details.meeting.title ?? "Untitled meeting")}`, `Meeting ID: ${details.meeting.id}`];
|
|
1641
|
+
if (details.meeting.description !== null)
|
|
1642
|
+
parts.push("## Description", quote(details.meeting.description));
|
|
1643
|
+
for (const summary of details.summaries) {
|
|
1644
|
+
parts.push(`## ${heading(summary.title ?? "Summary")}`);
|
|
1645
|
+
if (summary.content !== null)
|
|
1646
|
+
parts.push(quote(summary.content));
|
|
1647
|
+
else {
|
|
1648
|
+
if (summary.overview !== null)
|
|
1649
|
+
parts.push(quote(summary.overview));
|
|
1650
|
+
for (const section of summary.sections)
|
|
1651
|
+
parts.push(`### ${heading(section.label)}`, quote(section.text));
|
|
1652
|
+
if (summary.nextSteps.length > 0)
|
|
1653
|
+
parts.push("### Next steps", summary.nextSteps.map((step) => `- ${markdown(step)}`).join("\n"));
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
for (const part of transcripts) {
|
|
1657
|
+
parts.push(`## Transcript ${part.transcript.id}`, `Source: ${heading(part.transcript.source)}`);
|
|
1658
|
+
if (part.transcript.supersededAt !== null)
|
|
1659
|
+
parts.push("Version: superseded");
|
|
1660
|
+
for (const row of [...part.rows].sort((a, b) => a.position - b.position))
|
|
1661
|
+
parts.push(`[${timestamp(row.startMs)} \u2013 ${timestamp(row.endMs)}]${row.speakerName === null ? "" : ` ${heading(row.speakerName)}`}`, quote(row.text));
|
|
1662
|
+
}
|
|
1663
|
+
content = `${parts.join("\n\n")}
|
|
1664
|
+
`;
|
|
1665
|
+
}
|
|
1666
|
+
return {
|
|
1667
|
+
meetingId: details.meeting.id,
|
|
1668
|
+
format: options.format,
|
|
1669
|
+
filename: `meeting-${details.meeting.id}${options.transcriptId === void 0 ? "" : `-transcript-${options.transcriptId}`}.${options.format === "markdown" ? "md" : "vtt"}`,
|
|
1670
|
+
content
|
|
1671
|
+
};
|
|
1672
|
+
}, "exportMeeting");
|
|
1673
|
+
|
|
1674
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/payment.js
|
|
1675
|
+
var FACT_TYPES = ["fact", "statement", "question", "decision", "promise"];
|
|
1676
|
+
var PAYMENT_DIRECTIONS = ["to_us", "from_us"];
|
|
1677
|
+
var PAYMENT_STATES = ["expected", "paid", "cancelled"];
|
|
1678
|
+
var invalid2 = /* @__PURE__ */ __name((message) => {
|
|
1679
|
+
throw new CliError("validation_error", message);
|
|
1680
|
+
}, "invalid");
|
|
1681
|
+
var CURRENCIES = new Set(Intl.supportedValuesOf("currency"));
|
|
1682
|
+
var AMOUNT = /^(\d{1,15})(?:\.(\d{1,2}))?$/;
|
|
1683
|
+
var COUNTERPARTY = /^(person|organization|project):[1-9]\d*$/;
|
|
1684
|
+
var amountOf = /* @__PURE__ */ __name((value) => {
|
|
1685
|
+
const match = AMOUNT.exec(typeof value === "number" ? String(value) : typeof value === "string" ? value.trim() : "");
|
|
1686
|
+
if (!match)
|
|
1687
|
+
return invalid2("a payment's amount is a positive number with at most 2 decimals, such as 1200.50");
|
|
1688
|
+
const amount = `${BigInt(match[1] ?? "0")}.${(match[2] ?? "").padEnd(2, "0")}`;
|
|
1689
|
+
if (amount === "0.00")
|
|
1690
|
+
return invalid2("a payment's amount is more than 0");
|
|
1691
|
+
return amount;
|
|
1692
|
+
}, "amountOf");
|
|
1693
|
+
var dateOf = /* @__PURE__ */ __name((value) => {
|
|
1694
|
+
const date = typeof value === "string" ? value.trim() : "";
|
|
1695
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(date) || (/* @__PURE__ */ new Date(`${date}T00:00:00Z`)).toISOString().slice(0, 10) !== date)
|
|
1696
|
+
return invalid2("a payment's dates are ISO dates, such as 2026-10-31");
|
|
1697
|
+
return date;
|
|
1698
|
+
}, "dateOf");
|
|
1699
|
+
var optionalText = /* @__PURE__ */ __name((value, what, limit) => {
|
|
1700
|
+
if (value === void 0 || value === null)
|
|
1701
|
+
return null;
|
|
1702
|
+
if (typeof value !== "string" || !value.trim() || value.length > limit || value.includes("\0"))
|
|
1703
|
+
return invalid2(`a payment's ${what} takes 1\u2013${limit} characters`);
|
|
1704
|
+
return value.trim();
|
|
1705
|
+
}, "optionalText");
|
|
1706
|
+
var oneOf = /* @__PURE__ */ __name((value, allowed, what) => {
|
|
1707
|
+
if (typeof value !== "string" || !allowed.includes(value))
|
|
1708
|
+
return invalid2(`a payment's ${what} is one of ${allowed.join(", ")}`);
|
|
1709
|
+
return value;
|
|
1710
|
+
}, "oneOf");
|
|
1711
|
+
var FIELDS = [
|
|
1712
|
+
"amount",
|
|
1713
|
+
"currency",
|
|
1714
|
+
"direction",
|
|
1715
|
+
"counterparty",
|
|
1716
|
+
"counterparty_name",
|
|
1717
|
+
"due_at",
|
|
1718
|
+
"state",
|
|
1719
|
+
"item",
|
|
1720
|
+
"paid_at"
|
|
1721
|
+
];
|
|
1722
|
+
var validatePayment = /* @__PURE__ */ __name((input) => {
|
|
1723
|
+
if (!input || typeof input !== "object" || Array.isArray(input))
|
|
1724
|
+
return invalid2("a payment is an object");
|
|
1725
|
+
const raw = input;
|
|
1726
|
+
const unknown = Object.keys(raw).filter((key) => !FIELDS.includes(key));
|
|
1727
|
+
if (unknown.length)
|
|
1728
|
+
return invalid2(`a payment has no field ${unknown.join(", ")}; its fields are ${FIELDS.join(", ")}`);
|
|
1729
|
+
const currency = typeof raw.currency === "string" ? raw.currency.trim().toUpperCase() : "";
|
|
1730
|
+
if (!/^[A-Z]{3}$/.test(currency) || !CURRENCIES.has(currency))
|
|
1731
|
+
return invalid2("a payment's currency is an ISO 4217 code, such as EUR or RUB");
|
|
1732
|
+
const counterparty = optionalText(raw.counterparty, "counterparty", 80);
|
|
1733
|
+
if (counterparty !== null && !COUNTERPARTY.test(counterparty))
|
|
1734
|
+
return invalid2("a payment's counterparty is a person:, organization: or project: reference");
|
|
1735
|
+
const state = oneOf(raw.state, PAYMENT_STATES, "state");
|
|
1736
|
+
if (raw.paid_at != null && state !== "paid")
|
|
1737
|
+
return invalid2("only a paid payment has paid_at");
|
|
1738
|
+
return {
|
|
1739
|
+
amount: amountOf(raw.amount),
|
|
1740
|
+
currency,
|
|
1741
|
+
direction: oneOf(raw.direction, PAYMENT_DIRECTIONS, "direction"),
|
|
1742
|
+
counterparty,
|
|
1743
|
+
counterparty_name: optionalText(raw.counterparty_name, "counterparty name", 200),
|
|
1744
|
+
due_at: raw.due_at === void 0 || raw.due_at === null ? null : dateOf(raw.due_at),
|
|
1745
|
+
state,
|
|
1746
|
+
item: optionalText(raw.item, "item", 200),
|
|
1747
|
+
// Left out when absent, so a finding staged before the field keeps its fingerprint.
|
|
1748
|
+
...raw.paid_at == null ? {} : { paid_at: dateOf(raw.paid_at) }
|
|
1749
|
+
};
|
|
1750
|
+
}, "validatePayment");
|
|
1751
|
+
var grouped = /* @__PURE__ */ __name((amount) => {
|
|
1752
|
+
const [whole = "0", cents = "00"] = amount.split(".");
|
|
1753
|
+
const digits = whole.replace(/\B(?=(\d{3})+(?!\d))/g, " ");
|
|
1754
|
+
return cents === "00" ? digits : `${digits}.${cents}`;
|
|
1755
|
+
}, "grouped");
|
|
1756
|
+
var paymentTitle = /* @__PURE__ */ __name((fact) => {
|
|
1757
|
+
const payment = fact.payment;
|
|
1758
|
+
if (!payment)
|
|
1759
|
+
return "";
|
|
1760
|
+
const who = payment.counterparty_name ?? payment.counterparty;
|
|
1761
|
+
const way = payment.direction === "to_us" ? "to us" : "from us";
|
|
1762
|
+
const party = who === null ? "" : payment.direction === "to_us" ? ` from ${who}` : ` to ${who}`;
|
|
1763
|
+
const due = payment.due_at === null ? "" : `, due ${payment.due_at.slice(8, 10)}.${payment.due_at.slice(5, 7)}`;
|
|
1764
|
+
const item = payment.item === null ? "" : ` for ${payment.item}`;
|
|
1765
|
+
return `${grouped(payment.amount)} ${payment.currency} ${way}${party}${item}${due} (${payment.state})`;
|
|
1766
|
+
}, "paymentTitle");
|
|
1767
|
+
|
|
1768
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/findings-rules.js
|
|
1769
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
1770
|
+
|
|
1771
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/timestamp.js
|
|
1772
|
+
var meetingTimestamp = /* @__PURE__ */ __name((value, name) => {
|
|
1773
|
+
if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}T.+(?:Z|[+-]\d{2}:\d{2})$/i.test(value) || !Number.isFinite(Date.parse(value)))
|
|
1774
|
+
throw new CliError("validation_error", `${name} must be an ISO timestamp with a timezone, such as 2026-11-09T09:00:00Z`);
|
|
1775
|
+
const date = value.slice(0, 10);
|
|
1776
|
+
const instant = Date.parse(`${date}T00:00:00Z`);
|
|
1777
|
+
if (!Number.isFinite(instant) || new Date(instant).toISOString().slice(0, 10) !== date)
|
|
1778
|
+
throw new CliError("validation_error", `${name} contains an invalid calendar date`);
|
|
1779
|
+
return new Date(value).toISOString();
|
|
1780
|
+
}, "meetingTimestamp");
|
|
1781
|
+
|
|
1782
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/findings-rules.js
|
|
1783
|
+
var TASK_TYPES = ["bug", "feature", "chore"];
|
|
1784
|
+
var invalid3 = /* @__PURE__ */ __name((message) => {
|
|
1785
|
+
throw new CliError("validation_error", message);
|
|
1786
|
+
}, "invalid");
|
|
1787
|
+
var findingText = /* @__PURE__ */ __name((value, limit) => {
|
|
1788
|
+
if (typeof value !== "string" || !value.trim() || value.includes("\0") || value.length > limit)
|
|
1789
|
+
return invalid3(`finding text must contain 1\u2013${limit} characters without NUL`);
|
|
1790
|
+
return value.trim();
|
|
1791
|
+
}, "findingText");
|
|
1792
|
+
var findingHash = /* @__PURE__ */ __name((value) => createHash2("sha256").update(JSON.stringify(value)).digest("hex"), "findingHash");
|
|
1793
|
+
var snakeCase = /* @__PURE__ */ __name((key) => key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`), "snakeCase");
|
|
1794
|
+
var findingWhere = /* @__PURE__ */ __name((of) => {
|
|
1795
|
+
const id3 = typeof of.id === "string" ? of.id : null;
|
|
1796
|
+
const kind = typeof of.kind === "string" ? of.kind : null;
|
|
1797
|
+
return {
|
|
1798
|
+
where: id3 || kind ? ` in ${[id3, kind && `(${kind})`].filter(Boolean).join(" ")}` : "",
|
|
1799
|
+
named: { ...id3 ? { finding: id3 } : {}, ...kind ? { kind } : {} }
|
|
1800
|
+
};
|
|
1801
|
+
}, "findingWhere");
|
|
1802
|
+
var findingFields = /* @__PURE__ */ __name((value, allowed, noun, of = value) => {
|
|
1803
|
+
const unknown = Object.keys(value).filter((key) => !allowed.includes(key));
|
|
1804
|
+
if (!unknown.length)
|
|
1805
|
+
return;
|
|
1806
|
+
const fields = unknown.map(snakeCase);
|
|
1807
|
+
const takes = allowed.map(snakeCase);
|
|
1808
|
+
const { where, named } = findingWhere(of);
|
|
1809
|
+
throw new CliError("validation_error", `unknown ${noun} field${fields.length > 1 ? "s" : ""} ${fields.join(", ")}${where}; it takes ${takes.join(", ")}`, { reason: "finding.unknown-field", fields, allowed: takes, ...named });
|
|
1810
|
+
}, "findingFields");
|
|
1811
|
+
var findingNeeds = /* @__PURE__ */ __name((value, needed, noun) => {
|
|
1812
|
+
const missing = needed.filter((key) => value[key] === void 0);
|
|
1813
|
+
if (!missing.length)
|
|
1814
|
+
return;
|
|
1815
|
+
const fields = missing.map(snakeCase);
|
|
1816
|
+
const needs = needed.map(snakeCase);
|
|
1817
|
+
const { where, named } = findingWhere(value);
|
|
1818
|
+
throw new CliError("validation_error", `missing ${noun} field${fields.length > 1 ? "s" : ""} ${fields.join(", ")}${where}; it needs ${needs.join(", ")}`, { reason: "finding.missing-field", fields, needs, ...named });
|
|
1819
|
+
}, "findingNeeds");
|
|
1820
|
+
var SUBJECT = /^(person|organization|project):[1-9]\d*$|^task:[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$/;
|
|
1821
|
+
var validEvidence = /* @__PURE__ */ __name((raw, rules) => {
|
|
1822
|
+
if (!Array.isArray(raw) || raw.length < 1 || raw.length > 8)
|
|
1823
|
+
return invalid3(`a finding requires 1\u20138 cited ${rules.cited}s`);
|
|
1824
|
+
const evidence = raw.map((item) => {
|
|
1825
|
+
if (!item || typeof item !== "object")
|
|
1826
|
+
return invalid3("finding evidence is a reference and fingerprint");
|
|
1827
|
+
findingFields(item, ["reference", "fingerprint"], rules.singular);
|
|
1828
|
+
if (typeof item.reference !== "string" || typeof item.fingerprint !== "string")
|
|
1829
|
+
return invalid3("evidence requires a reference and fingerprint");
|
|
1830
|
+
const reference2 = rules.reference(item.reference);
|
|
1831
|
+
if (!/^[a-f0-9]{64}$/.test(item.fingerprint))
|
|
1832
|
+
return invalid3(`finding evidence requires exact ${rules.cited} references and fingerprints`);
|
|
1833
|
+
return { reference: reference2, fingerprint: item.fingerprint };
|
|
1834
|
+
}).sort((a, b) => a.reference.localeCompare(b.reference));
|
|
1835
|
+
if (new Set(evidence.map((item) => item.reference)).size !== evidence.length)
|
|
1836
|
+
return invalid3(`duplicate evidence ${rules.cited}`);
|
|
1837
|
+
return evidence;
|
|
1838
|
+
}, "validEvidence");
|
|
1839
|
+
var findingId = /* @__PURE__ */ __name((raw, ids2) => {
|
|
1840
|
+
const id3 = findingText(raw, 64);
|
|
1841
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/.test(id3) || ids2.has(id3))
|
|
1842
|
+
return invalid3("finding IDs must be unique simple keys");
|
|
1843
|
+
ids2.add(id3);
|
|
1844
|
+
return id3;
|
|
1845
|
+
}, "findingId");
|
|
1846
|
+
var validateFinding = /* @__PURE__ */ __name((finding, rules, ids2) => {
|
|
1847
|
+
if (!finding || typeof finding !== "object")
|
|
1848
|
+
return invalid3("a finding is an object");
|
|
1849
|
+
const id3 = findingId(finding.id, ids2);
|
|
1850
|
+
const project = finding.project === void 0 && rules.anySubject ? void 0 : findingText(finding.project, 64);
|
|
1851
|
+
if (project !== void 0 && !/^project:[1-9]\d*$/.test(project))
|
|
1852
|
+
return invalid3("a finding names a project reference");
|
|
1853
|
+
if (finding.subject !== void 0 && (!rules.anySubject || !SUBJECT.test(findingText(finding.subject, 80))))
|
|
1854
|
+
return invalid3("a finding's subject is a person:, organization:, task: or project: reference");
|
|
1855
|
+
if (finding.kind === "task" && project === void 0 && !rules.inboxTasks)
|
|
1856
|
+
return invalid3("a task finding names the project the task goes in");
|
|
1857
|
+
const evidence = validEvidence(finding.evidence, rules);
|
|
1858
|
+
const base = {
|
|
1859
|
+
id: id3,
|
|
1860
|
+
...project === void 0 ? {} : { project },
|
|
1861
|
+
...finding.subject === void 0 ? {} : { subject: finding.subject },
|
|
1862
|
+
evidence
|
|
1863
|
+
};
|
|
1864
|
+
if (finding.kind === "fact") {
|
|
1865
|
+
findingFields(finding, ["id", "project", "subject", "evidence", "kind", "type", "statement"], rules.singular);
|
|
1866
|
+
if (finding.type === "payment")
|
|
1867
|
+
return invalid3("a payment is a finding of kind payment; money is a payments row, not a fact");
|
|
1868
|
+
if (!FACT_TYPES.includes(finding.type))
|
|
1869
|
+
return invalid3("unknown fact finding type");
|
|
1870
|
+
return { ...base, kind: "fact", type: finding.type, statement: findingText(finding.statement, 2e3) };
|
|
1871
|
+
}
|
|
1872
|
+
if (finding.kind === "payment" && rules.payments) {
|
|
1873
|
+
findingFields(finding, ["id", "project", "subject", "evidence", "kind", "statement", "payment", "supersedes"], rules.singular);
|
|
1874
|
+
if (finding.supersedes !== void 0 && !/^invoice:[1-9]\d*$/.test(String(finding.supersedes)))
|
|
1875
|
+
return invalid3("a payment finding supersedes an invoice: reference, the expected payment it settles or voids");
|
|
1876
|
+
const payment = validatePayment(finding.payment);
|
|
1877
|
+
if (payment.state === "expected" && finding.supersedes !== void 0)
|
|
1878
|
+
return invalid3("an expected payment supersedes nothing; a paid or cancelled one supersedes its invoice");
|
|
1879
|
+
if (payment.state === "cancelled" && finding.supersedes === void 0)
|
|
1880
|
+
return invalid3("a cancelled payment names the invoice: it cancels in supersedes");
|
|
1881
|
+
if (payment.state === "expected" && !/^(person|organization):/.test(payment.counterparty ?? ""))
|
|
1882
|
+
return invalid3("an expected payment becomes an invoice, which names its counterparty as a person: or organization:");
|
|
1883
|
+
return {
|
|
1884
|
+
...base,
|
|
1885
|
+
kind: "payment",
|
|
1886
|
+
...finding.statement === void 0 ? {} : { statement: findingText(finding.statement, 2e3) },
|
|
1887
|
+
payment,
|
|
1888
|
+
...finding.supersedes === void 0 ? {} : { supersedes: finding.supersedes }
|
|
1889
|
+
};
|
|
1890
|
+
}
|
|
1891
|
+
if (finding.kind !== "task")
|
|
1892
|
+
return invalid3(`a finding is a fact${rules.payments ? ", payment" : ""} or task`);
|
|
1893
|
+
findingFields(finding, [
|
|
1894
|
+
"id",
|
|
1895
|
+
"project",
|
|
1896
|
+
"evidence",
|
|
1897
|
+
"kind",
|
|
1898
|
+
"type",
|
|
1899
|
+
"title",
|
|
1900
|
+
"reason",
|
|
1901
|
+
"commitment",
|
|
1902
|
+
"dueAt",
|
|
1903
|
+
"dueEvidence",
|
|
1904
|
+
"assignee",
|
|
1905
|
+
"assigneeEvidence"
|
|
1906
|
+
], rules.singular);
|
|
1907
|
+
if (!TASK_TYPES.includes(finding.type))
|
|
1908
|
+
return invalid3("a task finding type is bug, chore or feature");
|
|
1909
|
+
if (!["explicit", "inferred"].includes(finding.commitment))
|
|
1910
|
+
return invalid3("task commitment must be explicit or inferred");
|
|
1911
|
+
if (finding.dueAt === void 0 !== (finding.dueEvidence === void 0))
|
|
1912
|
+
return invalid3(`due_at comes with due_evidence: the ${rules.cited} references of this finding's evidence that give the date, as a list of strings such as ["<reference>"]`);
|
|
1913
|
+
if (finding.assignee === void 0 !== (finding.assigneeEvidence === void 0))
|
|
1914
|
+
return invalid3(`assignee comes with assignee_evidence: the ${rules.cited} references of this finding's evidence that name them, as a list of strings such as ["<reference>"]`);
|
|
1915
|
+
if (finding.assignee !== void 0 && (typeof finding.assignee !== "string" || !/^person:[1-9]\d*$/.test(finding.assignee)))
|
|
1916
|
+
return invalid3("an assignee must be a person reference");
|
|
1917
|
+
return {
|
|
1918
|
+
...base,
|
|
1919
|
+
kind: "task",
|
|
1920
|
+
type: finding.type,
|
|
1921
|
+
title: findingText(finding.title, 300),
|
|
1922
|
+
reason: findingText(finding.reason, 2e3),
|
|
1923
|
+
commitment: finding.commitment,
|
|
1924
|
+
...finding.dueAt === void 0 ? {} : {
|
|
1925
|
+
dueAt: meetingTimestamp(finding.dueAt, "a task's due_at"),
|
|
1926
|
+
dueEvidence: support(finding.dueEvidence, evidence, "due_evidence")
|
|
1927
|
+
},
|
|
1928
|
+
...finding.assignee === void 0 ? {} : {
|
|
1929
|
+
assignee: finding.assignee,
|
|
1930
|
+
assigneeEvidence: support(finding.assigneeEvidence, evidence, "assignee_evidence")
|
|
1931
|
+
}
|
|
1932
|
+
};
|
|
1933
|
+
}, "validateFinding");
|
|
1934
|
+
var support = /* @__PURE__ */ __name((value, evidence, field) => {
|
|
1935
|
+
if (!Array.isArray(value) || value.length < 1 || value.length > 8 || value.some((ref) => typeof ref !== "string" || !evidence.some((item) => item.reference === ref)))
|
|
1936
|
+
return invalid3(`${field} lists 1\u20138 references this finding's evidence cites, as plain strings such as ["<reference>"], not evidence objects`);
|
|
1937
|
+
return [...new Set(value)].sort();
|
|
1938
|
+
}, "support");
|
|
1939
|
+
var validateBatch = /* @__PURE__ */ __name((input, rules, most, one) => {
|
|
1940
|
+
if (!input || typeof input !== "object" || Buffer.byteLength(JSON.stringify(input), "utf8") > 65536)
|
|
1941
|
+
return invalid3(`${rules.plural} take at most 65536 UTF-8 bytes`);
|
|
1942
|
+
findingFields(input, ["schemaVersion", "key", "extractor", "findings"], rules.singular);
|
|
1943
|
+
if (input.schemaVersion !== 1 || !Array.isArray(input.findings) || input.findings.length < 1 || input.findings.length > most)
|
|
1944
|
+
return invalid3(`schemaVersion 1 takes 1\u2013${most} ${rules.plural}`);
|
|
1945
|
+
const key = findingText(input.key, 64);
|
|
1946
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/.test(key))
|
|
1947
|
+
return invalid3("a findings key uses letters, digits, dot, colon, underscore or hyphen");
|
|
1948
|
+
const ids2 = /* @__PURE__ */ new Set();
|
|
1949
|
+
const findings = input.findings.map((finding) => one(finding, ids2));
|
|
1950
|
+
return { schemaVersion: 1, key, extractor: findingText(input.extractor, 200), findings };
|
|
1951
|
+
}, "validateBatch");
|
|
1952
|
+
var validateFindings = /* @__PURE__ */ __name((input, rules) => validateBatch(input, rules, 16, (finding, ids2) => validateFinding(finding, rules, ids2)), "validateFindings");
|
|
1953
|
+
var findingFingerprint = /* @__PURE__ */ __name(({ id: _id, ...finding }) => findingHash(finding), "findingFingerprint");
|
|
1954
|
+
|
|
1955
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/findings.js
|
|
1956
|
+
var MEETING_FINDINGS_KIND = "meeting_findings";
|
|
1957
|
+
var cue = /* @__PURE__ */ __name((raw) => {
|
|
1958
|
+
const reference2 = canonicalMeetingReference(raw);
|
|
1959
|
+
if (parseMeetingReference(reference2).cuePosition === void 0)
|
|
1960
|
+
throw new CliError("validation_error", "finding evidence requires exact cue references and fingerprints");
|
|
1961
|
+
return reference2;
|
|
1962
|
+
}, "cue");
|
|
1963
|
+
var validateMeetingFindings = /* @__PURE__ */ __name((input) => validateFindings(input, { plural: "meeting findings", singular: "meeting finding", cited: "cue", reference: cue }), "validateMeetingFindings");
|
|
1964
|
+
var meetingFindingFingerprint = findingFingerprint;
|
|
1965
|
+
|
|
1966
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/result-items.js
|
|
1967
|
+
var text3 = string();
|
|
1968
|
+
var identifier = pipe(text3, minLength(1));
|
|
1969
|
+
var nullableText = nullable(text3);
|
|
1970
|
+
var count3 = pipe(number(), integer(), minValue(0));
|
|
1971
|
+
var flag = boolean();
|
|
1972
|
+
var scope = strictObject({ provider: text3, account: text3 });
|
|
1973
|
+
var run = strictObject({
|
|
1974
|
+
meetings: count3,
|
|
1975
|
+
participants: count3,
|
|
1976
|
+
transcript_rows: count3,
|
|
1977
|
+
summaries: count3,
|
|
1978
|
+
warnings: array(strictObject({ external_id: text3, message: text3 })),
|
|
1979
|
+
timezone: optional(text3)
|
|
1980
|
+
});
|
|
1981
|
+
var exported = union([
|
|
1982
|
+
strictObject({ meeting_id: identifier, format: picklist(["markdown", "vtt"]), filename: text3, content: text3 }),
|
|
1983
|
+
strictObject({ meeting_id: identifier, format: picklist(["markdown", "vtt"]), output: text3 })
|
|
1984
|
+
]);
|
|
1985
|
+
var eventChange = strictObject({
|
|
1986
|
+
action: literal("event.link"),
|
|
1987
|
+
event_id: nullable(identifier),
|
|
1988
|
+
expected_event_id: optional(nullable(identifier))
|
|
1989
|
+
});
|
|
1990
|
+
var personChange = strictObject({
|
|
1991
|
+
action: literal("person.link"),
|
|
1992
|
+
participant_id: identifier,
|
|
1993
|
+
person_uid: text3,
|
|
1994
|
+
expected_person_uid: optional(nullableText),
|
|
1995
|
+
target_account_ids: optional(array(identifier))
|
|
1996
|
+
});
|
|
1997
|
+
var eventResult = strictObject({
|
|
1998
|
+
meeting_id: identifier,
|
|
1999
|
+
event_id: nullable(identifier),
|
|
2000
|
+
previous_event_id: nullable(identifier),
|
|
2001
|
+
changed: flag
|
|
2002
|
+
});
|
|
2003
|
+
var personResult = strictObject({
|
|
2004
|
+
meeting_id: identifier,
|
|
2005
|
+
participant_id: identifier,
|
|
2006
|
+
person_uid: text3,
|
|
2007
|
+
previous_person_uid: nullableText,
|
|
2008
|
+
changed: flag
|
|
2009
|
+
});
|
|
2010
|
+
var meetingChange = strictObject({
|
|
2011
|
+
scope,
|
|
2012
|
+
account_id: identifier,
|
|
2013
|
+
meeting_id: identifier,
|
|
2014
|
+
change: union([eventChange, personChange]),
|
|
2015
|
+
applied: flag,
|
|
2016
|
+
result: optional(union([eventResult, personResult]))
|
|
2017
|
+
});
|
|
2018
|
+
var recognition = strictObject({
|
|
2019
|
+
engine: text3,
|
|
2020
|
+
model: text3,
|
|
2021
|
+
version: optional(text3),
|
|
2022
|
+
timing: optional(picklist(["fixed-windows", "recognition-segments"]))
|
|
2023
|
+
});
|
|
2024
|
+
var transcription = union([
|
|
2025
|
+
strictObject({
|
|
2026
|
+
applied: literal(false),
|
|
2027
|
+
account_id: identifier,
|
|
2028
|
+
external_id: text3,
|
|
2029
|
+
segments: count3,
|
|
2030
|
+
media: strictObject({
|
|
2031
|
+
id: text3,
|
|
2032
|
+
content_hash: text3,
|
|
2033
|
+
size: count3,
|
|
2034
|
+
duration_ms: count3,
|
|
2035
|
+
format: text3,
|
|
2036
|
+
sample_rate: count3,
|
|
2037
|
+
channels: count3,
|
|
2038
|
+
recognition
|
|
2039
|
+
})
|
|
2040
|
+
}),
|
|
2041
|
+
strictObject({
|
|
2042
|
+
applied: literal(true),
|
|
2043
|
+
account_id: identifier,
|
|
2044
|
+
external_id: text3,
|
|
2045
|
+
meeting_id: identifier,
|
|
2046
|
+
created: flag,
|
|
2047
|
+
inserted_transcripts: count3,
|
|
2048
|
+
replayed_transcripts: count3,
|
|
2049
|
+
superseded_transcripts: count3,
|
|
2050
|
+
segments: count3,
|
|
2051
|
+
media_sha256: text3,
|
|
2052
|
+
engine: text3,
|
|
2053
|
+
model: text3,
|
|
2054
|
+
model_version: nullableText,
|
|
2055
|
+
timing: picklist(["fixed-windows", "recognition-segments"])
|
|
2056
|
+
})
|
|
2057
|
+
]);
|
|
2058
|
+
var embeddingModel = strictObject({ key: text3, dims: count3, kind: picklist(["local", "remote"]), model: text3 });
|
|
2059
|
+
var embedding = union([
|
|
2060
|
+
strictObject({
|
|
2061
|
+
account_id: identifier,
|
|
2062
|
+
model: embeddingModel,
|
|
2063
|
+
status: strictObject({ chunks: count3, embedded: count3 }),
|
|
2064
|
+
applied: literal(false),
|
|
2065
|
+
scope: literal("existing-current-chunks"),
|
|
2066
|
+
rebuild_required: literal("explicit")
|
|
2067
|
+
}),
|
|
2068
|
+
strictObject({
|
|
2069
|
+
account_id: identifier,
|
|
2070
|
+
model: embeddingModel,
|
|
2071
|
+
saved: count3,
|
|
2072
|
+
skipped: count3,
|
|
2073
|
+
has_more: flag,
|
|
2074
|
+
next_hash: optional(text3),
|
|
2075
|
+
applied: literal(true),
|
|
2076
|
+
rebuild: strictObject({
|
|
2077
|
+
transcripts: count3,
|
|
2078
|
+
chunks: count3,
|
|
2079
|
+
has_more: flag,
|
|
2080
|
+
next_transcript_id: optional(identifier)
|
|
2081
|
+
})
|
|
2082
|
+
})
|
|
2083
|
+
]);
|
|
2084
|
+
var repair = strictObject({
|
|
2085
|
+
account_id: identifier,
|
|
2086
|
+
applied: flag,
|
|
2087
|
+
transcripts: count3,
|
|
2088
|
+
languages: array(strictObject({ language: nullableText, transcripts: count3 }))
|
|
2089
|
+
});
|
|
2090
|
+
var MEETING_RESULT_ENTITIES = {
|
|
2091
|
+
meeting_ingestion: run,
|
|
2092
|
+
meeting_export: exported,
|
|
2093
|
+
meeting_association: meetingChange,
|
|
2094
|
+
meeting_transcription: transcription,
|
|
2095
|
+
meeting_embedding: embedding,
|
|
2096
|
+
meeting_repair: repair
|
|
2097
|
+
};
|
|
2098
|
+
|
|
2099
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/event-query.js
|
|
2100
|
+
var EVENT_QUERY = defineQuery({
|
|
2101
|
+
entity: "event",
|
|
2102
|
+
backend: "sql",
|
|
2103
|
+
fields: [
|
|
2104
|
+
{ name: "id", type: "num", operators: ["term", "range"], example: "id:1" },
|
|
2105
|
+
{ name: "origin", type: "enum", operators: ["term"], values: ["auto", "owner"], example: "origin:owner" },
|
|
2106
|
+
...["starts_at", "ends_at", "created_at", "updated_at"].map((name) => ({
|
|
2107
|
+
name,
|
|
2108
|
+
type: "time",
|
|
2109
|
+
operators: ["term", "range"],
|
|
2110
|
+
example: `${name}>=2026-01-01`
|
|
2111
|
+
}))
|
|
2112
|
+
]
|
|
2113
|
+
});
|
|
2114
|
+
|
|
2115
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/events.js
|
|
2116
|
+
var linkEvent = /* @__PURE__ */ __name(async (store, details, now = Date.now()) => {
|
|
2117
|
+
const current = await store.meeting(details.meeting.id);
|
|
2118
|
+
if (!current)
|
|
2119
|
+
return null;
|
|
2120
|
+
const { meeting: meeting2, series } = current;
|
|
2121
|
+
if (meeting2.eventId !== null)
|
|
2122
|
+
return (await store.events()).find((e) => e.id === meeting2.eventId) ?? null;
|
|
2123
|
+
const candidates = meeting2.startedAt === null ? [] : await store.eventCandidates({
|
|
2124
|
+
meetingSeriesId: meeting2.meetingSeriesId,
|
|
2125
|
+
joinUrl: meeting2.joinUrl,
|
|
2126
|
+
startsAt: meeting2.startedAt,
|
|
2127
|
+
endsAt: meeting2.endedAt ?? meeting2.startedAt
|
|
2128
|
+
});
|
|
2129
|
+
if (candidates.length > 1) {
|
|
2130
|
+
await store.reviewMeetingLink?.(meeting2.id, candidates.map(({ id: id3 }) => id3), now);
|
|
2131
|
+
return null;
|
|
2132
|
+
}
|
|
2133
|
+
let event2 = candidates[0];
|
|
2134
|
+
if (!event2) {
|
|
2135
|
+
let eventSeriesId = series?.eventSeriesId ?? null;
|
|
2136
|
+
if (series?.kind === "recurring" && eventSeriesId === null) {
|
|
2137
|
+
const created = await store.createEventSeries({ title: series.title, recurrence: null, origin: "auto" }, now);
|
|
2138
|
+
eventSeriesId = created.id;
|
|
2139
|
+
await store.setEventSeries(series.id, eventSeriesId, now);
|
|
2140
|
+
}
|
|
2141
|
+
event2 = await store.createEvent({
|
|
2142
|
+
eventSeriesId,
|
|
2143
|
+
title: meeting2.title,
|
|
2144
|
+
description: meeting2.description,
|
|
2145
|
+
location: meeting2.location,
|
|
2146
|
+
startsAt: meeting2.startedAt,
|
|
2147
|
+
endsAt: meeting2.endedAt,
|
|
2148
|
+
timezone: meeting2.timezone,
|
|
2149
|
+
origin: "auto",
|
|
2150
|
+
deletedAt: null
|
|
2151
|
+
}, now);
|
|
2152
|
+
}
|
|
2153
|
+
await store.linkMeeting(meeting2.id, event2.id, now);
|
|
2154
|
+
const linked = await store.meeting(meeting2.id);
|
|
2155
|
+
return (await store.events()).find((e) => e.id === linked?.meeting.eventId) ?? null;
|
|
2156
|
+
}, "linkEvent");
|
|
2157
|
+
|
|
2158
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/hit-query.js
|
|
2159
|
+
var context = {
|
|
2160
|
+
command: "search meetings",
|
|
2161
|
+
guide: "https://github.com/WireCatLabs/cli-core/blob/main/docs/search/query-language.md#\u0432\u0441\u0442\u0440\u0435\u0447\u0438"
|
|
2162
|
+
};
|
|
2163
|
+
var words = ["term", "phrase"];
|
|
2164
|
+
var MOST_LINES_APART = 20;
|
|
2165
|
+
var near = /* @__PURE__ */ __name((node) => {
|
|
2166
|
+
if (node.slop !== void 0 && node.slop > MOST_LINES_APART)
|
|
2167
|
+
queryError("query.invalid-number", node.span, `words at most ${MOST_LINES_APART} lines apart: "a b"~${MOST_LINES_APART}`, context);
|
|
2168
|
+
}, "near");
|
|
2169
|
+
var MEETING_HIT_QUERY = defineQuery({
|
|
2170
|
+
entity: "meeting_hit",
|
|
2171
|
+
backend: "sql",
|
|
2172
|
+
fields: [
|
|
2173
|
+
{
|
|
2174
|
+
name: "text",
|
|
2175
|
+
type: "txt",
|
|
2176
|
+
operators: words,
|
|
2177
|
+
example: "text:budget",
|
|
2178
|
+
relation: "a passage with the word in any form, or a spelling speech recognition garbled",
|
|
2179
|
+
validate: near
|
|
2180
|
+
},
|
|
2181
|
+
{
|
|
2182
|
+
name: "exact",
|
|
2183
|
+
type: "txt",
|
|
2184
|
+
operators: words,
|
|
2185
|
+
example: "exact:budget",
|
|
2186
|
+
relation: "a passage with the word as typed: no other forms, no garbled spellings",
|
|
2187
|
+
validate: near
|
|
2188
|
+
},
|
|
2189
|
+
{
|
|
2190
|
+
name: "from",
|
|
2191
|
+
type: "kw",
|
|
2192
|
+
operators: words,
|
|
2193
|
+
example: 'from:"Alice Synthetic"',
|
|
2194
|
+
relation: "a line said or a chat message written by this person; attendance is --identity-id"
|
|
2195
|
+
}
|
|
2196
|
+
]
|
|
2197
|
+
});
|
|
2198
|
+
var MEETING_FIELDS = defineQuery({
|
|
2199
|
+
entity: "meeting_hit",
|
|
2200
|
+
backend: "sql",
|
|
2201
|
+
fields: [
|
|
2202
|
+
...MEETING_HIT_QUERY.fields,
|
|
2203
|
+
{
|
|
2204
|
+
name: "date",
|
|
2205
|
+
type: "time",
|
|
2206
|
+
operators: ["term", "range"],
|
|
2207
|
+
example: "date>=30d",
|
|
2208
|
+
relation: "meetings that started then; the same as --since-time and --until-time"
|
|
2209
|
+
},
|
|
2210
|
+
...["project", "tag", "topic"].map((name) => ({
|
|
2211
|
+
name,
|
|
2212
|
+
type: "kw",
|
|
2213
|
+
operators: words,
|
|
2214
|
+
example: `${name}:"Example name"`,
|
|
2215
|
+
relation: `meetings in this ${name}, by name or alias; the same as --${name}`
|
|
2216
|
+
}))
|
|
2217
|
+
]
|
|
2218
|
+
});
|
|
2219
|
+
var parseMeetingQuery = /* @__PURE__ */ __name((query) => validateQuery(parseLucene(query, { defaultField: "text", proximity: true, ...context }), MEETING_HIT_QUERY, context), "parseMeetingQuery");
|
|
2220
|
+
|
|
2221
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/language.js
|
|
2222
|
+
var LATIN_WORDS = {
|
|
2223
|
+
en: ["the", "and", "is", "that", "you", "this", "what", "have", "with", "are"],
|
|
2224
|
+
es: ["el", "los", "las", "por", "pero", "para", "est\xE1", "muy", "tambi\xE9n", "hay"],
|
|
2225
|
+
de: ["der", "und", "ist", "nicht", "das", "ich", "wir", "mit", "auch", "ein"],
|
|
2226
|
+
fr: ["le", "les", "est", "une", "pas", "je", "vous", "nous", "avec", "mais"],
|
|
2227
|
+
it: ["gli", "della", "sono", "perch\xE9", "anche", "questo", "molto", "che", "di", "\xE8"],
|
|
2228
|
+
pt: ["n\xE3o", "voc\xEA", "isso", "muito", "ent\xE3o", "com", "uma", "tamb\xE9m", "mas", "eu"]
|
|
2229
|
+
};
|
|
2230
|
+
var LATIN_LANGUAGE = new Map(Object.entries(LATIN_WORDS).flatMap(([language, words2]) => words2.map((word) => [word, language])));
|
|
2231
|
+
var UKRAINIAN = /[іїєґ]/giu;
|
|
2232
|
+
var CYRILLIC = new RegExp("\\p{Script=Cyrillic}", "gu");
|
|
2233
|
+
var LATIN = new RegExp("\\p{Script=Latin}", "gu");
|
|
2234
|
+
var MIN_LETTERS = 20;
|
|
2235
|
+
var DOMINANT = 0.75;
|
|
2236
|
+
var countOf = /* @__PURE__ */ __name((text5, pattern2) => text5.match(pattern2)?.length ?? 0, "countOf");
|
|
2237
|
+
var latinLanguage = /* @__PURE__ */ __name((texts) => {
|
|
2238
|
+
const votes = /* @__PURE__ */ new Map();
|
|
2239
|
+
for (const text5 of texts)
|
|
2240
|
+
for (const word of text5.toLowerCase().split(/[^\p{L}]+/u)) {
|
|
2241
|
+
const language = LATIN_LANGUAGE.get(word);
|
|
2242
|
+
if (language)
|
|
2243
|
+
votes.set(language, (votes.get(language) ?? 0) + 1);
|
|
2244
|
+
}
|
|
2245
|
+
const [first, second] = [...votes].sort((a, b) => b[1] - a[1]);
|
|
2246
|
+
if (!first || first[1] < 3 || second && first[1] < 2 * second[1])
|
|
2247
|
+
return null;
|
|
2248
|
+
return first[0];
|
|
2249
|
+
}, "latinLanguage");
|
|
2250
|
+
var transcriptLanguage = /* @__PURE__ */ __name((texts) => {
|
|
2251
|
+
const all = [...texts];
|
|
2252
|
+
let cyrillic = 0;
|
|
2253
|
+
let latin = 0;
|
|
2254
|
+
let ukrainian = 0;
|
|
2255
|
+
for (const text5 of all) {
|
|
2256
|
+
cyrillic += countOf(text5, CYRILLIC);
|
|
2257
|
+
latin += countOf(text5, LATIN);
|
|
2258
|
+
ukrainian += countOf(text5, UKRAINIAN);
|
|
2259
|
+
}
|
|
2260
|
+
const letters = cyrillic + latin;
|
|
2261
|
+
if (letters < MIN_LETTERS)
|
|
2262
|
+
return null;
|
|
2263
|
+
if (cyrillic / letters >= DOMINANT)
|
|
2264
|
+
return ukrainian / cyrillic >= 0.01 ? "uk" : "ru";
|
|
2265
|
+
if (latin / letters >= DOMINANT)
|
|
2266
|
+
return latinLanguage(all);
|
|
2267
|
+
return null;
|
|
2268
|
+
}, "transcriptLanguage");
|
|
2269
|
+
|
|
2270
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/ingest.js
|
|
2271
|
+
var contentHash = /* @__PURE__ */ __name(async (text5) => {
|
|
2272
|
+
const bytes = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(text5));
|
|
2273
|
+
return Array.from(new Uint8Array(bytes), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
2274
|
+
}, "contentHash");
|
|
2275
|
+
var speakerPosition = /* @__PURE__ */ __name((name, participants) => {
|
|
2276
|
+
if (name === null)
|
|
2277
|
+
return null;
|
|
2278
|
+
const matches2 = participants.flatMap((p, i) => p.displayName === name ? [i] : []);
|
|
2279
|
+
return matches2.length === 1 ? matches2[0] ?? null : null;
|
|
2280
|
+
}, "speakerPosition");
|
|
2281
|
+
var transcriptInput = /* @__PURE__ */ __name(async (lines, participants, source, hashText = JSON.stringify(lines), format = null) => ({
|
|
2282
|
+
source,
|
|
2283
|
+
format,
|
|
2284
|
+
language: transcriptLanguage(lines.map((line2) => line2.text)),
|
|
2285
|
+
contentHash: await contentHash(hashText),
|
|
2286
|
+
externalCreatedAt: null,
|
|
2287
|
+
metadata: null,
|
|
2288
|
+
deletedAt: null,
|
|
2289
|
+
rows: lines.map((line2, position) => ({
|
|
2290
|
+
position,
|
|
2291
|
+
startMs: line2.startMs,
|
|
2292
|
+
endMs: line2.endMs,
|
|
2293
|
+
speakerParticipantPosition: speakerPosition(line2.speaker, participants),
|
|
2294
|
+
speakerName: line2.speaker,
|
|
2295
|
+
text: line2.text,
|
|
2296
|
+
normalizedText: null,
|
|
2297
|
+
metadata: null
|
|
2298
|
+
}))
|
|
2299
|
+
}), "transcriptInput");
|
|
2300
|
+
var timestamp2 = /* @__PURE__ */ __name((value) => {
|
|
2301
|
+
const time = Date.parse(value);
|
|
2302
|
+
if (!Number.isFinite(time))
|
|
2303
|
+
throw new Error("Invalid meeting timestamp");
|
|
2304
|
+
return time;
|
|
2305
|
+
}, "timestamp");
|
|
2306
|
+
|
|
2307
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/transcript-text.js
|
|
2308
|
+
var TranscriptTextError = class extends Error {
|
|
2309
|
+
static {
|
|
2310
|
+
__name(this, "TranscriptTextError");
|
|
2311
|
+
}
|
|
2312
|
+
name = "TranscriptTextError";
|
|
2313
|
+
};
|
|
2314
|
+
var HEADER = {
|
|
2315
|
+
"\u0412\u0441\u0442\u0440\u0435\u0447\u0430: ": "title",
|
|
2316
|
+
"\u0414\u0430\u0442\u0430: ": "date",
|
|
2317
|
+
"Zoom ID: ": "meetingId",
|
|
2318
|
+
"\u0413\u043E\u0432\u043E\u0440\u044F\u0442: ": "speakers"
|
|
2319
|
+
};
|
|
2320
|
+
var LINE = /^\[(\d{2,}):([0-5]\d):([0-5]\d)\]\s*(?:([^:\n]{1,60}):\s*)?([\s\S]*)$/;
|
|
2321
|
+
var RULE = /^[—–-]{10,}[^\n]*(?:\n|$)/;
|
|
2322
|
+
var EMPTY = /* @__PURE__ */ new Set(["", "\u2014", "-"]);
|
|
2323
|
+
var parseTranscriptText = /* @__PURE__ */ __name((input) => {
|
|
2324
|
+
const text5 = input.replace(/^/, "").replace(/\r\n?/g, "\n");
|
|
2325
|
+
const header = { title: null, date: null, meetingId: null, speakers: [] };
|
|
2326
|
+
let sawHeader = false;
|
|
2327
|
+
for (const line2 of text5.split("\n")) {
|
|
2328
|
+
if (!line2.trim())
|
|
2329
|
+
break;
|
|
2330
|
+
for (const [prefix, key] of Object.entries(HEADER)) {
|
|
2331
|
+
if (!line2.startsWith(prefix))
|
|
2332
|
+
continue;
|
|
2333
|
+
sawHeader = true;
|
|
2334
|
+
const value = line2.slice(prefix.length).trim();
|
|
2335
|
+
if (key === "speakers")
|
|
2336
|
+
header.speakers = value.split(",").map((name) => name.trim()).filter((name) => !EMPTY.has(name));
|
|
2337
|
+
else
|
|
2338
|
+
header[key] = EMPTY.has(value) ? null : value;
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
if (!sawHeader)
|
|
2342
|
+
throw new TranscriptTextError('a text transcript starts with a header such as "\u0412\u0441\u0442\u0440\u0435\u0447\u0430: \u2026"');
|
|
2343
|
+
const found = [];
|
|
2344
|
+
for (const block of text5.split(/\n\s*\n/)) {
|
|
2345
|
+
const match = LINE.exec(block.trim().replace(RULE, ""));
|
|
2346
|
+
if (!match)
|
|
2347
|
+
continue;
|
|
2348
|
+
const [, hours = "0", minutes = "0", seconds = "0", speaker, said = ""] = match;
|
|
2349
|
+
found.push({
|
|
2350
|
+
startMs: ((Number(hours) * 60 + Number(minutes)) * 60 + Number(seconds)) * 1e3,
|
|
2351
|
+
speaker: speaker?.trim() || null,
|
|
2352
|
+
text: said.trim()
|
|
2353
|
+
});
|
|
2354
|
+
}
|
|
2355
|
+
const lines = found.map((line2, at) => ({
|
|
2356
|
+
...line2,
|
|
2357
|
+
endMs: Math.max(line2.startMs, found[at + 1]?.startMs ?? line2.startMs)
|
|
2358
|
+
}));
|
|
2359
|
+
return { header, lines };
|
|
2360
|
+
}, "parseTranscriptText");
|
|
2361
|
+
|
|
2362
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/vtt.js
|
|
2363
|
+
var VttError = class extends Error {
|
|
2364
|
+
static {
|
|
2365
|
+
__name(this, "VttError");
|
|
2366
|
+
}
|
|
2367
|
+
name = "VttError";
|
|
2368
|
+
};
|
|
2369
|
+
var TIMESTAMP = /^(?:(\d+):)?([0-5]\d):([0-5]\d)\.(\d{3})$/;
|
|
2370
|
+
var SKIPPED = /^(NOTE|STYLE|REGION)(\s|$)/;
|
|
2371
|
+
var millis = /* @__PURE__ */ __name((stamp, lineNo) => {
|
|
2372
|
+
const match = TIMESTAMP.exec(stamp);
|
|
2373
|
+
if (!match)
|
|
2374
|
+
throw new VttError(`line ${lineNo}: "${stamp}" is not a WebVTT timestamp`);
|
|
2375
|
+
const [, hours = "0", minutes = "0", seconds = "0", ms = "0"] = match;
|
|
2376
|
+
return ((Number(hours) * 60 + Number(minutes)) * 60 + Number(seconds)) * 1e3 + Number(ms);
|
|
2377
|
+
}, "millis");
|
|
2378
|
+
var splitSpeaker = /* @__PURE__ */ __name((text5) => {
|
|
2379
|
+
const firstLine = text5.split("\n", 1)[0] ?? "";
|
|
2380
|
+
const at = firstLine.indexOf(": ");
|
|
2381
|
+
if (at <= 0)
|
|
2382
|
+
return { speaker: null, text: text5 };
|
|
2383
|
+
return { speaker: firstLine.slice(0, at).trim(), text: text5.slice(at + 2) };
|
|
2384
|
+
}, "splitSpeaker");
|
|
2385
|
+
var parseVtt = /* @__PURE__ */ __name((input) => {
|
|
2386
|
+
const lines = input.replace(/^/, "").split(/\r\n|\r|\n/);
|
|
2387
|
+
if (!/^WEBVTT([ \t].*)?$/.test(lines[0] ?? ""))
|
|
2388
|
+
throw new VttError('line 1: a WebVTT file starts with "WEBVTT"');
|
|
2389
|
+
const cues = [];
|
|
2390
|
+
let i = lines.findIndex((line2) => line2.trim() === "");
|
|
2391
|
+
if (i < 0)
|
|
2392
|
+
return [];
|
|
2393
|
+
while (i < lines.length) {
|
|
2394
|
+
while (i < lines.length && lines[i]?.trim() === "")
|
|
2395
|
+
i++;
|
|
2396
|
+
const start = i;
|
|
2397
|
+
while (i < lines.length && lines[i]?.trim() !== "")
|
|
2398
|
+
i++;
|
|
2399
|
+
const block = lines.slice(start, i);
|
|
2400
|
+
if (block.length === 0 || SKIPPED.test(block[0] ?? ""))
|
|
2401
|
+
continue;
|
|
2402
|
+
const timingAt = block.findIndex((line2) => line2.includes("-->"));
|
|
2403
|
+
if (timingAt < 0 || timingAt > 1)
|
|
2404
|
+
throw new VttError(`line ${start + 1}: a cue has no timing line`);
|
|
2405
|
+
const lineNo = start + timingAt + 1;
|
|
2406
|
+
const [from = "", rest = ""] = (block[timingAt] ?? "").split("-->");
|
|
2407
|
+
const to = rest.trim().split(/\s+/)[0] ?? "";
|
|
2408
|
+
const text5 = block.slice(timingAt + 1).join("\n").trim();
|
|
2409
|
+
cues.push({ startMs: millis(from.trim(), lineNo), endMs: millis(to, lineNo), ...splitSpeaker(text5) });
|
|
2410
|
+
}
|
|
2411
|
+
return cues;
|
|
2412
|
+
}, "parseVtt");
|
|
2413
|
+
|
|
2414
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/import.js
|
|
2415
|
+
var importFiles = /* @__PURE__ */ __name(async (files, store, now = Date.now()) => {
|
|
2416
|
+
const report = { meetings: 0, participants: 0, transcriptRows: 0, summaries: 0, warnings: [] };
|
|
2417
|
+
for (const file of files) {
|
|
2418
|
+
try {
|
|
2419
|
+
const format = file.format ?? "vtt";
|
|
2420
|
+
const lines = format === "text" ? parseTranscriptText(file.content).lines : parseVtt(file.content);
|
|
2421
|
+
const participants = file.participants ?? [];
|
|
2422
|
+
const details = await store.saveMeeting({
|
|
2423
|
+
meeting: file.meeting,
|
|
2424
|
+
participants: file.participants,
|
|
2425
|
+
transcripts: [await transcriptInput(lines, participants, file.source ?? "file", file.content, format)],
|
|
2426
|
+
now,
|
|
2427
|
+
fromFile: true
|
|
2428
|
+
});
|
|
2429
|
+
await linkEvent(store, details, now);
|
|
2430
|
+
report.meetings++;
|
|
2431
|
+
report.participants += participants.length;
|
|
2432
|
+
report.transcriptRows += lines.length;
|
|
2433
|
+
} catch (error) {
|
|
2434
|
+
report.warnings.push({
|
|
2435
|
+
externalId: file.meeting.externalId,
|
|
2436
|
+
message: error instanceof Error ? error.message : "Meeting import failed"
|
|
2437
|
+
});
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
const zones = new Set(files.map((file) => file.meeting.timezone).filter((zone2) => zone2 !== null && zone2 !== void 0));
|
|
2441
|
+
const [zone] = zones;
|
|
2442
|
+
if (zones.size === 1 && zone)
|
|
2443
|
+
report.timezone = zone;
|
|
2444
|
+
return report;
|
|
2445
|
+
}, "importFiles");
|
|
2446
|
+
|
|
2447
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/links.js
|
|
2448
|
+
var CHAT_MESSAGES_READ = 1e5;
|
|
2449
|
+
|
|
2450
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/meeting-management.js
|
|
2451
|
+
var nonempty = /* @__PURE__ */ __name((value, name) => {
|
|
2452
|
+
if (typeof value !== "string" || !value.trim())
|
|
2453
|
+
throw new CliError("validation_error", `${name} must be nonempty`);
|
|
2454
|
+
return value;
|
|
2455
|
+
}, "nonempty");
|
|
2456
|
+
var validateMeetingChange = /* @__PURE__ */ __name((change, create) => {
|
|
2457
|
+
if (!change || typeof change !== "object" || Array.isArray(change) || Object.keys(change).some((key) => !["title", "kind", "startTime", "durationMinutes", "timezone", "agenda"].includes(key)))
|
|
2458
|
+
throw new CliError("validation_error", "unsupported meeting change field");
|
|
2459
|
+
const result = {};
|
|
2460
|
+
if (change.title !== void 0)
|
|
2461
|
+
result.title = nonempty(change.title, "meeting title");
|
|
2462
|
+
if (create && result.title === void 0)
|
|
2463
|
+
throw new CliError("validation_error", "meeting title is required");
|
|
2464
|
+
if (change.kind !== void 0) {
|
|
2465
|
+
if (change.kind !== "instant" && change.kind !== "scheduled")
|
|
2466
|
+
throw new CliError("validation_error", "only instant or scheduled meeting kinds are supported");
|
|
2467
|
+
result.kind = change.kind;
|
|
2468
|
+
}
|
|
2469
|
+
if (change.startTime !== void 0) {
|
|
2470
|
+
result.startTime = meetingTimestamp(change.startTime, "meeting start");
|
|
2471
|
+
}
|
|
2472
|
+
if (change.durationMinutes !== void 0) {
|
|
2473
|
+
if (!Number.isSafeInteger(change.durationMinutes) || change.durationMinutes <= 0 || change.durationMinutes > 1440)
|
|
2474
|
+
throw new CliError("validation_error", "meeting duration must be an integer from 1 to 1440 minutes");
|
|
2475
|
+
result.durationMinutes = change.durationMinutes;
|
|
2476
|
+
}
|
|
2477
|
+
if (change.timezone !== void 0) {
|
|
2478
|
+
if (typeof change.timezone !== "string" || !change.timezone.trim())
|
|
2479
|
+
throw new CliError("validation_error", "meeting timezone must be a valid IANA timezone");
|
|
2480
|
+
try {
|
|
2481
|
+
new Intl.DateTimeFormat("en", { timeZone: change.timezone }).format();
|
|
2482
|
+
} catch {
|
|
2483
|
+
throw new CliError("validation_error", "meeting timezone must be a valid IANA timezone");
|
|
2484
|
+
}
|
|
2485
|
+
result.timezone = change.timezone;
|
|
2486
|
+
}
|
|
2487
|
+
if (change.agenda !== void 0) {
|
|
2488
|
+
if (typeof change.agenda !== "string")
|
|
2489
|
+
throw new CliError("validation_error", "meeting agenda must be text");
|
|
2490
|
+
result.agenda = change.agenda;
|
|
2491
|
+
}
|
|
2492
|
+
if (create) {
|
|
2493
|
+
result.kind ??= "scheduled";
|
|
2494
|
+
if (result.kind === "scheduled" && result.startTime === void 0)
|
|
2495
|
+
throw new CliError("validation_error", "scheduled meeting start is required");
|
|
2496
|
+
} else if (!Object.keys(result).length)
|
|
2497
|
+
throw new CliError("validation_error", "at least one meeting change is required");
|
|
2498
|
+
return Object.freeze(result);
|
|
2499
|
+
}, "validateMeetingChange");
|
|
2500
|
+
|
|
2501
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/passage.js
|
|
2502
|
+
var meetingHitContextLimits = /* @__PURE__ */ __name((options = {}) => {
|
|
2503
|
+
const { before = 3, after = 3, bytes = 65536, max_read_bytes = 4194304, expected_fingerprint } = options;
|
|
2504
|
+
if (![before, after].every((value) => Number.isSafeInteger(value) && value >= 0) || before + after > 999 || !Number.isSafeInteger(bytes) || bytes < 2 || bytes > 4194304 || !Number.isSafeInteger(max_read_bytes) || max_read_bytes < 1 || max_read_bytes > 67108864 || expected_fingerprint !== void 0 && (typeof expected_fingerprint !== "string" || !/^[a-f0-9]{64}$/.test(expected_fingerprint)))
|
|
2505
|
+
throw new CliError("validation_error", "context takes 0\u2013999 surrounding cues, 2\u20134194304 output bytes and a bounded read budget");
|
|
2506
|
+
return { before, after, bytes, max_read_bytes };
|
|
2507
|
+
}, "meetingHitContextLimits");
|
|
2508
|
+
var validateMeetingPassage = /* @__PURE__ */ __name((reference2, options) => {
|
|
2509
|
+
meetingHitContextLimits(options);
|
|
2510
|
+
if (typeof reference2 !== "string" || !reference2.trim() || reference2.length > 200 || options.format !== void 0 && !["json", "text", "markdown"].includes(options.format))
|
|
2511
|
+
throw new CliError("validation_error", "choose a cue reference and json, text or markdown output");
|
|
2512
|
+
}, "validateMeetingPassage");
|
|
2513
|
+
|
|
2514
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/preparation-context.js
|
|
2515
|
+
var validateMeetingPreparationContext = /* @__PURE__ */ __name((original) => {
|
|
2516
|
+
if (!original || typeof original !== "object" || Array.isArray(original))
|
|
2517
|
+
throw new CliError("validation_error", "meeting preparation context is required");
|
|
2518
|
+
const input = { ...original };
|
|
2519
|
+
for (const key of Object.keys(input))
|
|
2520
|
+
if (!["accountId", "meetingId", "seriesId", "updatedAt", "limit", "maxReadBytes", "signal"].includes(key))
|
|
2521
|
+
throw new CliError("validation_error", `unknown preparation context field: ${key}`);
|
|
2522
|
+
if (input.signal !== void 0 && !(input.signal instanceof AbortSignal))
|
|
2523
|
+
throw new CliError("validation_error", "signal must be an AbortSignal");
|
|
2524
|
+
input.signal?.throwIfAborted();
|
|
2525
|
+
for (const key of ["accountId", "meetingId", "seriesId"])
|
|
2526
|
+
if (!Number.isSafeInteger(input[key]) || input[key] <= 0)
|
|
2527
|
+
throw new CliError("validation_error", `${key} must be a positive safe integer`);
|
|
2528
|
+
if (!Number.isSafeInteger(input.updatedAt) || Math.abs(input.updatedAt) > 864e13)
|
|
2529
|
+
throw new CliError("validation_error", "updatedAt must be an absolute timestamp");
|
|
2530
|
+
const limit = input.limit === void 0 ? 20 : input.limit;
|
|
2531
|
+
const maxReadBytes = input.maxReadBytes === void 0 ? 262144 : input.maxReadBytes;
|
|
2532
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100)
|
|
2533
|
+
throw new CliError("validation_error", "limit must be an integer from 1 to 100");
|
|
2534
|
+
if (!Number.isSafeInteger(maxReadBytes) || maxReadBytes < 1 || maxReadBytes > 4194304)
|
|
2535
|
+
throw new CliError("validation_error", "maxReadBytes must be an integer from 1 to 4194304");
|
|
2536
|
+
return { ...input, limit, maxReadBytes };
|
|
2537
|
+
}, "validateMeetingPreparationContext");
|
|
2538
|
+
|
|
2539
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/project-evidence-answer.js
|
|
2540
|
+
var count4 = pipe(number(), integer(), minValue(0));
|
|
2541
|
+
var id = pipe(string(), minLength(1));
|
|
2542
|
+
var meetingProjectEvidence = strictObject({
|
|
2543
|
+
schema_version: literal(1),
|
|
2544
|
+
kind: literal("meeting_project_evidence"),
|
|
2545
|
+
account_id: id,
|
|
2546
|
+
query: string(),
|
|
2547
|
+
project: strictObject({ id, name: string(), key: nullable(string()) }),
|
|
2548
|
+
term: strictObject({
|
|
2549
|
+
name: string(),
|
|
2550
|
+
kind: picklist(["canonical", "key", "alias"]),
|
|
2551
|
+
alias_id: optional(id)
|
|
2552
|
+
}),
|
|
2553
|
+
hits: array(meetingHit),
|
|
2554
|
+
association: literal("unconfirmed-word-evidence"),
|
|
2555
|
+
vocabulary_fingerprint: id,
|
|
2556
|
+
selection: strictObject({
|
|
2557
|
+
meeting_id: optional(id),
|
|
2558
|
+
identity_id: optional(id),
|
|
2559
|
+
person_id: optional(id),
|
|
2560
|
+
tag_id: optional(id),
|
|
2561
|
+
event_id: optional(id),
|
|
2562
|
+
series_id: optional(id),
|
|
2563
|
+
since: optional(isoTime),
|
|
2564
|
+
until: optional(isoTime)
|
|
2565
|
+
}),
|
|
2566
|
+
limits: strictObject({ limit: count4, max_read_bytes: count4, max_vocabulary_read_bytes: count4, max_terms: count4 }),
|
|
2567
|
+
page: pageSchema,
|
|
2568
|
+
coverage: strictObject({
|
|
2569
|
+
archive_completeness: literal("unknown"),
|
|
2570
|
+
current_revisions: literal(true),
|
|
2571
|
+
indexing: picklist(["ready", "pending"]),
|
|
2572
|
+
index_completeness: literal("unknown"),
|
|
2573
|
+
term_index: count4,
|
|
2574
|
+
terms_total: count4,
|
|
2575
|
+
remaining_terms: count4,
|
|
2576
|
+
duplicates: literal("may-repeat-between-terms")
|
|
2577
|
+
})
|
|
2578
|
+
});
|
|
2579
|
+
var PAGE_NEXT3 = STEPS.find((step) => step.id === "page.next");
|
|
2580
|
+
var meetingProjectEvidenceAnswer = /* @__PURE__ */ __name((page, prepared, command = "meetings projects evidence") => {
|
|
2581
|
+
const { options } = prepared;
|
|
2582
|
+
const selection = {};
|
|
2583
|
+
for (const [field, value] of [
|
|
2584
|
+
["meeting_id", options.meetingId],
|
|
2585
|
+
["identity_id", options.participantIdentityId],
|
|
2586
|
+
["person_id", options.personId],
|
|
2587
|
+
["tag_id", options.tagId],
|
|
2588
|
+
["event_id", options.eventId],
|
|
2589
|
+
["series_id", options.meetingSeriesId]
|
|
2590
|
+
])
|
|
2591
|
+
if (value !== void 0)
|
|
2592
|
+
selection[field] = String(value);
|
|
2593
|
+
if (options.since !== void 0)
|
|
2594
|
+
selection.since = new Date(options.since).toISOString();
|
|
2595
|
+
if (options.until !== void 0)
|
|
2596
|
+
selection.until = new Date(options.until).toISOString();
|
|
2597
|
+
const cursor = page.nextCursor ?? void 0;
|
|
2598
|
+
if (page.hasMore !== (cursor !== void 0))
|
|
2599
|
+
throw new CliError("invalid_response", "project evidence continuation is inconsistent");
|
|
2600
|
+
const item = {
|
|
2601
|
+
schema_version: 1,
|
|
2602
|
+
kind: "meeting_project_evidence",
|
|
2603
|
+
account_id: String(page.accountId),
|
|
2604
|
+
query: page.query,
|
|
2605
|
+
project: page.project,
|
|
2606
|
+
term: {
|
|
2607
|
+
name: page.term.name,
|
|
2608
|
+
kind: page.term.kind,
|
|
2609
|
+
...page.term.aliasId === void 0 ? {} : { alias_id: page.term.aliasId }
|
|
2610
|
+
},
|
|
2611
|
+
hits: page.hits.map(meetingHitItem),
|
|
2612
|
+
association: page.association,
|
|
2613
|
+
vocabulary_fingerprint: page.vocabularyFingerprint,
|
|
2614
|
+
selection,
|
|
2615
|
+
limits: {
|
|
2616
|
+
limit: page.limits.limit,
|
|
2617
|
+
max_read_bytes: page.limits.maxReadBytes,
|
|
2618
|
+
max_vocabulary_read_bytes: page.limits.maxVocabularyReadBytes,
|
|
2619
|
+
max_terms: page.limits.maxTerms
|
|
2620
|
+
},
|
|
2621
|
+
page: {
|
|
2622
|
+
mode: "cursor",
|
|
2623
|
+
limit: page.limits.limit,
|
|
2624
|
+
has_more: page.hasMore,
|
|
2625
|
+
...cursor === void 0 ? {} : { next_cursor: cursor }
|
|
2626
|
+
},
|
|
2627
|
+
coverage: {
|
|
2628
|
+
archive_completeness: page.coverage.archiveCompleteness,
|
|
2629
|
+
current_revisions: page.coverage.currentRevisions,
|
|
2630
|
+
indexing: page.coverage.indexing,
|
|
2631
|
+
index_completeness: page.coverage.indexCompleteness,
|
|
2632
|
+
term_index: page.coverage.termIndex,
|
|
2633
|
+
terms_total: page.coverage.termsTotal,
|
|
2634
|
+
remaining_terms: page.coverage.remainingTerms,
|
|
2635
|
+
duplicates: page.coverage.duplicates
|
|
2636
|
+
}
|
|
2637
|
+
};
|
|
2638
|
+
if (!safeParse(meetingProjectEvidence, item).success)
|
|
2639
|
+
throw new CliError("invalid_response", "project evidence does not match its answer contract");
|
|
2640
|
+
return {
|
|
2641
|
+
item,
|
|
2642
|
+
...cursor === void 0 ? {} : {
|
|
2643
|
+
next: [
|
|
2644
|
+
stepOf(PAGE_NEXT3, {
|
|
2645
|
+
command,
|
|
2646
|
+
args: {
|
|
2647
|
+
project: prepared.project,
|
|
2648
|
+
query: prepared.query,
|
|
2649
|
+
cursor,
|
|
2650
|
+
limit: page.limits.limit,
|
|
2651
|
+
max_read_bytes: page.limits.maxReadBytes
|
|
2652
|
+
},
|
|
2653
|
+
values: { shown: page.hits.length }
|
|
2654
|
+
})
|
|
2655
|
+
]
|
|
2656
|
+
}
|
|
2657
|
+
};
|
|
2658
|
+
}, "meetingProjectEvidenceAnswer");
|
|
2659
|
+
|
|
2660
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/search-validation.js
|
|
2661
|
+
var validateMeetingHitSearch = /* @__PURE__ */ __name((query, options = {}) => {
|
|
2662
|
+
const integer3 = /* @__PURE__ */ __name((value, low, high) => Number.isSafeInteger(value) && value >= low && value <= high, "integer");
|
|
2663
|
+
if (typeof query !== "string" || !query.trim() || query.includes("\0") || new TextEncoder().encode(query).byteLength > 65536 || !integer3(options.limit ?? 100, 1, 1e3) || !integer3(options.maxReadBytes ?? 4194304, 1, 67108864) || [
|
|
2664
|
+
options.meetingId,
|
|
2665
|
+
options.participantIdentityId,
|
|
2666
|
+
options.personId,
|
|
2667
|
+
options.projectId,
|
|
2668
|
+
options.tagId,
|
|
2669
|
+
options.eventId,
|
|
2670
|
+
options.meetingSeriesId
|
|
2671
|
+
].some((value) => value !== void 0 && !integer3(value, 1, Number.MAX_SAFE_INTEGER)) || [options.since, options.until].some((value) => value !== void 0 && !integer3(value, -864e13, 864e13)) || options.since !== void 0 && options.until !== void 0 && options.since > options.until || options.after !== void 0 && (typeof options.after !== "string" || !/^[A-Za-z0-9_-]{1,1000}$/.test(options.after)))
|
|
2672
|
+
throw new CliError("validation_error", "invalid bounded meeting search query, cursor or limits");
|
|
2673
|
+
for (const name of [options.project, options.tag, options.topic])
|
|
2674
|
+
if (name !== void 0 && (typeof name !== "string" || !name.trim() || name.length > 200 || /[\p{Cc}\p{Cf}]/u.test(name)))
|
|
2675
|
+
throw new CliError("validation_error", "a meeting vocabulary name takes 1\u2013200 characters without control characters");
|
|
2676
|
+
if (options.project !== void 0 && options.projectId !== void 0 || [options.tag, options.topic, options.tagId].filter((value) => value !== void 0).length > 1)
|
|
2677
|
+
throw new CliError("validation_error", "choose one project selector and one tag or topic selector");
|
|
2678
|
+
}, "validateMeetingHitSearch");
|
|
2679
|
+
|
|
2680
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/project-evidence-query.js
|
|
2681
|
+
var ids = {
|
|
2682
|
+
meeting_id: "meetingId",
|
|
2683
|
+
identity_id: "participantIdentityId",
|
|
2684
|
+
person_id: "personId",
|
|
2685
|
+
tag_id: "tagId",
|
|
2686
|
+
event_id: "eventId",
|
|
2687
|
+
series_id: "meetingSeriesId"
|
|
2688
|
+
};
|
|
2689
|
+
var context2 = {
|
|
2690
|
+
command: "meetings projects evidence",
|
|
2691
|
+
guide: "https://github.com/WireCatLabs/cli-core/blob/main/docs/search/query-language.md"
|
|
2692
|
+
};
|
|
2693
|
+
var MEETING_PROJECT_EVIDENCE_QUERY = defineQuery({
|
|
2694
|
+
entity: "meeting_project_evidence",
|
|
2695
|
+
backend: "sql",
|
|
2696
|
+
fields: [
|
|
2697
|
+
...Object.keys(ids).map((name) => ({
|
|
2698
|
+
name,
|
|
2699
|
+
type: "num",
|
|
2700
|
+
operators: ["term"],
|
|
2701
|
+
example: `${name}:12`,
|
|
2702
|
+
placement: "and",
|
|
2703
|
+
relation: "meetings selected by this stored ID; identity selects participants, not speakers"
|
|
2704
|
+
})),
|
|
2705
|
+
{
|
|
2706
|
+
name: "started_at",
|
|
2707
|
+
type: "time",
|
|
2708
|
+
operators: ["term", "phrase", "range"],
|
|
2709
|
+
example: "started_at:[2026-10-01 TO 2026-10-31]",
|
|
2710
|
+
placement: "and",
|
|
2711
|
+
relation: "the meeting start time in UTC"
|
|
2712
|
+
}
|
|
2713
|
+
]
|
|
2714
|
+
});
|
|
2715
|
+
var requestKeys = /* @__PURE__ */ new Set(["query", "limit", "cursor", "maxReadBytes", "signal"]);
|
|
2716
|
+
var prepareMeetingProjectEvidence = /* @__PURE__ */ __name((project, request = {}, now = Date.now()) => {
|
|
2717
|
+
if (!request || typeof request !== "object" || Array.isArray(request) || Object.keys(request).some((key) => !requestKeys.has(key)) || typeof project !== "string" || !project.trim() || project.length > 200 || /[\p{Cc}\p{Cf}]/u.test(project) || request.query !== void 0 && typeof request.query !== "string")
|
|
2718
|
+
throw new CliError("validation_error", "expected an existing project and bounded evidence arguments");
|
|
2719
|
+
if (request.query !== void 0 && new TextEncoder().encode(request.query).byteLength > 8192 || [request.limit, request.maxReadBytes].some((value) => value !== void 0 && typeof value !== "number"))
|
|
2720
|
+
throw new CliError("validation_error", "invalid project evidence query or budget");
|
|
2721
|
+
request.signal?.throwIfAborted();
|
|
2722
|
+
const options = {
|
|
2723
|
+
limit: request.limit ?? 100,
|
|
2724
|
+
maxReadBytes: request.maxReadBytes ?? 4194304,
|
|
2725
|
+
...request.cursor === void 0 ? {} : { cursor: request.cursor },
|
|
2726
|
+
...request.signal === void 0 ? {} : { signal: request.signal }
|
|
2727
|
+
};
|
|
2728
|
+
const terms = /* @__PURE__ */ new Map();
|
|
2729
|
+
if (request.query?.trim()) {
|
|
2730
|
+
const ast = parseLucene(request.query, { defaultField: "none", ...context2 });
|
|
2731
|
+
validateQuery(ast, MEETING_PROJECT_EVIDENCE_QUERY, context2);
|
|
2732
|
+
const add = /* @__PURE__ */ __name((node) => {
|
|
2733
|
+
if (terms.has(node.field))
|
|
2734
|
+
queryError("query.unsupported-placement", node.span, "each field only once", context2);
|
|
2735
|
+
terms.set(node.field, node);
|
|
2736
|
+
}, "add");
|
|
2737
|
+
if (ast.root.kind === "predicate")
|
|
2738
|
+
add(ast.root);
|
|
2739
|
+
else
|
|
2740
|
+
for (const clause of ast.root.clauses) {
|
|
2741
|
+
if (clause.occur !== "must" || clause.node.kind !== "predicate")
|
|
2742
|
+
queryError("query.unsupported-placement", clause.node.span, "field:value terms joined by AND", context2);
|
|
2743
|
+
add(clause.node);
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
const frozen = [];
|
|
2747
|
+
for (const [field, key] of Object.entries(ids)) {
|
|
2748
|
+
const term2 = terms.get(field);
|
|
2749
|
+
if (!term2)
|
|
2750
|
+
continue;
|
|
2751
|
+
if (term2.operator !== "term" || !/^[1-9]\d*$/.test(term2.value) || !Number.isSafeInteger(Number(term2.value)))
|
|
2752
|
+
queryError("query.unsupported-operator", term2.span, "one positive safe integer ID", context2);
|
|
2753
|
+
options[key] = Number(term2.value);
|
|
2754
|
+
frozen.push(`${field}:${term2.value}`);
|
|
2755
|
+
}
|
|
2756
|
+
const term = terms.get("started_at");
|
|
2757
|
+
if (term) {
|
|
2758
|
+
const range = dateRange(term.value, term.operator === "range" ? term.upper ?? "*" : term.value, term.lower_inclusive !== false, term.upper_inclusive !== false, "UTC", term.span, now);
|
|
2759
|
+
if (range.lower !== void 0)
|
|
2760
|
+
options.since = range.lower + (range.lower_inclusive ? 0 : 1);
|
|
2761
|
+
if (range.upper !== void 0)
|
|
2762
|
+
options.until = range.upper - (range.upper_inclusive ? 0 : 1);
|
|
2763
|
+
frozen.push(`started_at:[${options.since === void 0 ? "*" : `"${new Date(options.since).toISOString()}"`} TO ${options.until === void 0 ? "*" : `"${new Date(options.until).toISOString()}"`}]`);
|
|
2764
|
+
}
|
|
2765
|
+
validateMeetingHitSearch(project, options);
|
|
2766
|
+
if (options.cursor !== void 0 && (typeof options.cursor !== "string" || !/^[A-Za-z0-9_-]{1,4096}$/.test(options.cursor)))
|
|
2767
|
+
throw new CliError("validation_error", "invalid project evidence cursor");
|
|
2768
|
+
return { project: project.trim(), options, query: frozen.join(" AND ") };
|
|
2769
|
+
}, "prepareMeetingProjectEvidence");
|
|
2770
|
+
|
|
2771
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/project-evidence.js
|
|
2772
|
+
var readMeetingProjectEvidence = /* @__PURE__ */ __name(async (read, project, request = {}, now = Date.now()) => {
|
|
2773
|
+
const prepared = prepareMeetingProjectEvidence(project, request, now);
|
|
2774
|
+
const page = await read(prepared.project, prepared.options);
|
|
2775
|
+
prepared.options.signal?.throwIfAborted();
|
|
2776
|
+
return meetingProjectEvidenceAnswer(page, prepared);
|
|
2777
|
+
}, "readMeetingProjectEvidence");
|
|
2778
|
+
|
|
2779
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/pull.js
|
|
2780
|
+
var participantInput = /* @__PURE__ */ __name((p, provider, occurrenceId2, position, accountId) => {
|
|
2781
|
+
const { identityExternalId, ...fields } = p;
|
|
2782
|
+
const externalId = identityExternalId ?? (p.email ? `email:${p.email.toLowerCase()}` : p.externalId) ?? `name:${p.displayName ?? "unknown"}@${accountId}/${occurrenceId2}:${position}`;
|
|
2783
|
+
return {
|
|
2784
|
+
...fields,
|
|
2785
|
+
identity: {
|
|
2786
|
+
provider,
|
|
2787
|
+
externalId,
|
|
2788
|
+
name: p.displayName,
|
|
2789
|
+
metadata: p.metadata,
|
|
2790
|
+
associatePerson: Boolean(identityExternalId?.trim() || p.email?.trim() || p.externalId?.trim())
|
|
2791
|
+
}
|
|
2792
|
+
};
|
|
2793
|
+
}, "participantInput");
|
|
2794
|
+
var pull = /* @__PURE__ */ __name(async (source, store, options) => {
|
|
2795
|
+
const now = options.now ?? Date.now();
|
|
2796
|
+
const lookbackMs = options.lookbackMs ?? 0;
|
|
2797
|
+
if (!Number.isSafeInteger(lookbackMs) || lookbackMs < 0 || lookbackMs > 31 * 864e5)
|
|
2798
|
+
throw new Error("lookbackMs must be an integer from 0 through 31 days");
|
|
2799
|
+
const since = options.since ?? await store.cursor(options.accountId) ?? new Date(now - 30 * 864e5).toISOString();
|
|
2800
|
+
timestamp2(since);
|
|
2801
|
+
const report = { meetings: 0, participants: 0, transcriptRows: 0, summaries: 0, warnings: [] };
|
|
2802
|
+
let failed = false;
|
|
2803
|
+
const from = timestamp2(since) - lookbackMs;
|
|
2804
|
+
const meetings = await source.meetings(lookbackMs === 0 ? since : new Date(from).toISOString());
|
|
2805
|
+
for (const m of meetings) {
|
|
2806
|
+
const id3 = m.occurrence.id;
|
|
2807
|
+
const read = /* @__PURE__ */ __name(async (part, call) => {
|
|
2808
|
+
try {
|
|
2809
|
+
return await call();
|
|
2810
|
+
} catch (error) {
|
|
2811
|
+
failed = true;
|
|
2812
|
+
const message = error instanceof Error ? error.message : "could not be read";
|
|
2813
|
+
report.warnings.push({ externalId: id3, message: `${part}: ${message}` });
|
|
2814
|
+
return void 0;
|
|
2815
|
+
}
|
|
2816
|
+
}, "read");
|
|
2817
|
+
try {
|
|
2818
|
+
const sourceParticipants = await read("participants", () => source.participants(id3));
|
|
2819
|
+
const participants = (sourceParticipants ?? []).map((p, i) => participantInput(p, source.provider, id3, i, options.accountId));
|
|
2820
|
+
const names = /* @__PURE__ */ new Map();
|
|
2821
|
+
for (const p of participants)
|
|
2822
|
+
if (p.displayName !== null) {
|
|
2823
|
+
const identities = names.get(p.displayName) ?? /* @__PURE__ */ new Set();
|
|
2824
|
+
identities.add(p.identity.externalId);
|
|
2825
|
+
names.set(p.displayName, identities);
|
|
2826
|
+
}
|
|
2827
|
+
if ([...names.values()].some((ids2) => ids2.size > 1))
|
|
2828
|
+
report.warnings.push({ externalId: id3, message: "Participant names are ambiguous" });
|
|
2829
|
+
const lines = await read("transcript", () => source.transcript(id3));
|
|
2830
|
+
const chat = await read("chat", () => source.chat(id3));
|
|
2831
|
+
const summary = await read("summary", () => source.summary(id3));
|
|
2832
|
+
const attachments = await read("files", () => source.files(id3));
|
|
2833
|
+
const startedAt = timestamp2(m.occurrence.startedAt);
|
|
2834
|
+
const endedAt = m.occurrence.endedAt === null ? null : timestamp2(m.occurrence.endedAt);
|
|
2835
|
+
if (endedAt !== null && endedAt < startedAt)
|
|
2836
|
+
throw new Error("Meeting ends before it starts");
|
|
2837
|
+
const meeting2 = {
|
|
2838
|
+
accountId: options.accountId,
|
|
2839
|
+
externalId: id3,
|
|
2840
|
+
title: m.occurrence.title,
|
|
2841
|
+
description: m.description ?? null,
|
|
2842
|
+
location: m.location ?? null,
|
|
2843
|
+
joinUrl: m.joinUrl ?? m.series?.joinUrl ?? null,
|
|
2844
|
+
startedAt,
|
|
2845
|
+
endedAt,
|
|
2846
|
+
durationMs: endedAt === null ? null : endedAt - startedAt,
|
|
2847
|
+
timezone: m.timezone ?? null,
|
|
2848
|
+
hostIdentityId: null,
|
|
2849
|
+
...sourceParticipants === void 0 ? {} : { participantsCount: sourceParticipants?.length ?? null },
|
|
2850
|
+
metadata: m.metadata ?? null,
|
|
2851
|
+
deletedAt: null
|
|
2852
|
+
};
|
|
2853
|
+
if (m.series)
|
|
2854
|
+
meeting2.series = {
|
|
2855
|
+
externalId: m.series.id,
|
|
2856
|
+
title: m.series.title,
|
|
2857
|
+
description: null,
|
|
2858
|
+
kind: m.series.kind ?? null,
|
|
2859
|
+
recurrence: m.series.recurrence ?? null,
|
|
2860
|
+
hostIdentityId: null,
|
|
2861
|
+
joinUrl: m.series.joinUrl ?? null,
|
|
2862
|
+
metadata: null,
|
|
2863
|
+
deletedAt: null
|
|
2864
|
+
};
|
|
2865
|
+
const linked = sourceParticipants !== void 0;
|
|
2866
|
+
const format = source.transcriptFormat ?? null;
|
|
2867
|
+
const transcripts = lines && linked ? [await transcriptInput(lines, participants, source.name, void 0, format)] : void 0;
|
|
2868
|
+
const details = await store.saveMeeting({
|
|
2869
|
+
meeting: meeting2,
|
|
2870
|
+
participants: sourceParticipants ? participants : void 0,
|
|
2871
|
+
transcripts,
|
|
2872
|
+
chat: chat?.map((line2) => ({
|
|
2873
|
+
externalId: null,
|
|
2874
|
+
sentAt: timestamp2(line2.sentAt),
|
|
2875
|
+
senderParticipantPosition: speakerPosition(line2.sender, participants),
|
|
2876
|
+
senderName: line2.sender,
|
|
2877
|
+
recipient: null,
|
|
2878
|
+
text: line2.text,
|
|
2879
|
+
normalizedText: null,
|
|
2880
|
+
metadata: null
|
|
2881
|
+
})),
|
|
2882
|
+
summaries: summary ? [
|
|
2883
|
+
{
|
|
2884
|
+
...summary,
|
|
2885
|
+
source: summary.source ?? source.name,
|
|
2886
|
+
content: summary.content ?? null,
|
|
2887
|
+
docUrl: summary.docUrl ?? null,
|
|
2888
|
+
externalCreatedAt: summary.externalCreatedAt ?? null,
|
|
2889
|
+
externalUpdatedAt: summary.externalUpdatedAt ?? null,
|
|
2890
|
+
metadata: summary.metadata ?? null
|
|
2891
|
+
}
|
|
2892
|
+
] : void 0,
|
|
2893
|
+
attachments: attachments ?? void 0,
|
|
2894
|
+
now
|
|
2895
|
+
});
|
|
2896
|
+
if (lines && !linked && !details.transcripts.some((t) => t.transcript.source === source.name && t.transcript.supersededAt === null))
|
|
2897
|
+
await store.saveMeeting({
|
|
2898
|
+
meeting: meeting2,
|
|
2899
|
+
transcripts: [await transcriptInput(lines, [], source.name, `${JSON.stringify(lines)}
|
|
2900
|
+
unlinked`, format)],
|
|
2901
|
+
now
|
|
2902
|
+
});
|
|
2903
|
+
await linkEvent(store, details, now);
|
|
2904
|
+
report.meetings++;
|
|
2905
|
+
report.participants += participants.length;
|
|
2906
|
+
report.transcriptRows += lines?.length ?? 0;
|
|
2907
|
+
report.summaries += summary ? 1 : 0;
|
|
2908
|
+
} catch (error) {
|
|
2909
|
+
failed = true;
|
|
2910
|
+
report.warnings.push({ externalId: id3, message: error instanceof Error ? error.message : "Meeting pull failed" });
|
|
2911
|
+
}
|
|
2912
|
+
}
|
|
2913
|
+
if (!failed)
|
|
2914
|
+
await store.setCursor(options.accountId, new Date(now).toISOString(), now);
|
|
2915
|
+
return report;
|
|
2916
|
+
}, "pull");
|
|
2917
|
+
|
|
2918
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/read-answers.js
|
|
2919
|
+
var text4 = string();
|
|
2920
|
+
var count5 = pipe(number(), integer(), minValue(0));
|
|
2921
|
+
var id2 = pipe(number(), integer(), minValue(1));
|
|
2922
|
+
var iso3 = /* @__PURE__ */ __name((ms) => ms === null ? null : new Date(ms).toISOString(), "iso");
|
|
2923
|
+
var meetingReview = strictObject({
|
|
2924
|
+
ref: reference,
|
|
2925
|
+
id: pipe(string(), minLength(1)),
|
|
2926
|
+
title: nullable(text4),
|
|
2927
|
+
started_at: nullable(isoTime),
|
|
2928
|
+
duration_ms: nullable(count5),
|
|
2929
|
+
participants_count: nullable(count5),
|
|
2930
|
+
projects: array(text4),
|
|
2931
|
+
/** Null when the meeting has no current transcript. */
|
|
2932
|
+
transcript: nullable(strictObject({ lines: count5, words: count5 })),
|
|
2933
|
+
/** The three who talked longest. */
|
|
2934
|
+
speakers: array(strictObject({ name: nullable(text4), talk_ms: count5 })),
|
|
2935
|
+
/** The newest stored summary; null when there is none. */
|
|
2936
|
+
summary: nullable(strictObject({
|
|
2937
|
+
source: text4,
|
|
2938
|
+
title: nullable(text4),
|
|
2939
|
+
overview: nullable(text4),
|
|
2940
|
+
next_steps: array(text4),
|
|
2941
|
+
url: nullable(text4)
|
|
2942
|
+
}))
|
|
2943
|
+
});
|
|
2944
|
+
var meetingLink = strictObject({
|
|
2945
|
+
url: text4,
|
|
2946
|
+
domain: nullable(text4),
|
|
2947
|
+
/** The Google Docs, Sheets, Slides, Forms or Drive file it names. */
|
|
2948
|
+
document_id: nullable(text4),
|
|
2949
|
+
count: count5,
|
|
2950
|
+
first_at: isoTime,
|
|
2951
|
+
last_at: isoTime,
|
|
2952
|
+
senders: array(text4),
|
|
2953
|
+
meetings: array(strictObject({ ref: reference, title: nullable(text4) }))
|
|
2954
|
+
});
|
|
2955
|
+
var meetingSpeaker = strictObject({
|
|
2956
|
+
/** `person:<id>`, `identity:<id>`, `name:<lowercased name>` or `unknown`. */
|
|
2957
|
+
key: text4,
|
|
2958
|
+
name: nullable(text4),
|
|
2959
|
+
person_id: nullable(id2),
|
|
2960
|
+
identity_id: nullable(id2),
|
|
2961
|
+
meetings: count5,
|
|
2962
|
+
lines: count5,
|
|
2963
|
+
words: count5,
|
|
2964
|
+
talk_ms: count5,
|
|
2965
|
+
/** This speaker's part of all talk time, 0–1. */
|
|
2966
|
+
share: pipe(number(), minValue(0), maxValue(1))
|
|
2967
|
+
});
|
|
2968
|
+
var meetingStats = strictObject({
|
|
2969
|
+
time_zone: text4,
|
|
2970
|
+
meetings: count5,
|
|
2971
|
+
lines: count5,
|
|
2972
|
+
words: count5,
|
|
2973
|
+
talk_ms: count5,
|
|
2974
|
+
/** `week_start` is the Monday, as a date in `time_zone`. */
|
|
2975
|
+
weeks: array(strictObject({ week_start: text4, meetings: count5, talk_ms: count5 })),
|
|
2976
|
+
top_speakers: array(meetingSpeaker)
|
|
2977
|
+
});
|
|
2978
|
+
var meetingCountsRow = strictObject({
|
|
2979
|
+
key: text4,
|
|
2980
|
+
name: nullable(text4),
|
|
2981
|
+
meetings: count5,
|
|
2982
|
+
minutes: count5,
|
|
2983
|
+
mean_minutes: nullable(number()),
|
|
2984
|
+
transcripts: count5
|
|
2985
|
+
});
|
|
2986
|
+
var meetingCounts = strictObject({
|
|
2987
|
+
by: picklist(["day", "week", "series"]),
|
|
2988
|
+
meetings: count5,
|
|
2989
|
+
minutes: count5,
|
|
2990
|
+
mean_minutes: nullable(number()),
|
|
2991
|
+
transcripts: count5,
|
|
2992
|
+
rows: array(meetingCountsRow),
|
|
2993
|
+
has_more: boolean()
|
|
2994
|
+
});
|
|
2995
|
+
var truncated = /* @__PURE__ */ __name((...why) => nullable(picklist(why)), "truncated");
|
|
2996
|
+
var meetingParticipants = strictObject({
|
|
2997
|
+
schema_version: literal(1),
|
|
2998
|
+
kind: literal("meeting_participants"),
|
|
2999
|
+
account_id: id2,
|
|
3000
|
+
query: text4,
|
|
3001
|
+
items: array(strictObject({
|
|
3002
|
+
participant_id: id2,
|
|
3003
|
+
meeting_id: id2,
|
|
3004
|
+
identity_id: id2,
|
|
3005
|
+
display_name: nullable(text4),
|
|
3006
|
+
email: nullable(text4)
|
|
3007
|
+
})),
|
|
3008
|
+
/** Several identities on one page are observations, never speaker attribution or person links. */
|
|
3009
|
+
ambiguity: strictObject({ scope: literal("page"), multiple_identities: boolean(), identity_ids: array(id2) }),
|
|
3010
|
+
coverage: strictObject({
|
|
3011
|
+
scanned: count5,
|
|
3012
|
+
read_bytes: count5,
|
|
3013
|
+
archive_completeness: literal("unknown"),
|
|
3014
|
+
truncated_by: truncated("limit", "scan_limit", "read_bytes")
|
|
3015
|
+
}),
|
|
3016
|
+
page: strictObject({
|
|
3017
|
+
mode: literal("cursor"),
|
|
3018
|
+
limit: count5,
|
|
3019
|
+
has_more: boolean(),
|
|
3020
|
+
next_cursor: optional(text4)
|
|
3021
|
+
})
|
|
3022
|
+
});
|
|
3023
|
+
var revision = picklist(["current", "superseded"]);
|
|
3024
|
+
var meetingPassage = strictObject({
|
|
3025
|
+
schema_version: literal(1),
|
|
3026
|
+
kind: literal("meeting_context"),
|
|
3027
|
+
source: reference,
|
|
3028
|
+
target_ref: reference,
|
|
3029
|
+
target_fingerprint: text4,
|
|
3030
|
+
fingerprint: text4,
|
|
3031
|
+
revision,
|
|
3032
|
+
limits: strictObject({ before: count5, after: count5, bytes: count5, max_read_bytes: count5 }),
|
|
3033
|
+
content_bytes: count5,
|
|
3034
|
+
coverage: strictObject({
|
|
3035
|
+
included: count5,
|
|
3036
|
+
before: count5,
|
|
3037
|
+
after: count5,
|
|
3038
|
+
has_before: boolean(),
|
|
3039
|
+
has_after: boolean(),
|
|
3040
|
+
truncated_by: truncated("bytes"),
|
|
3041
|
+
before_ref: nullable(reference),
|
|
3042
|
+
after_ref: nullable(reference),
|
|
3043
|
+
continuation: literal("anchor-inclusive"),
|
|
3044
|
+
archive_completeness: literal("unknown"),
|
|
3045
|
+
input: literal("bounded-meeting-context")
|
|
3046
|
+
}),
|
|
3047
|
+
items: array(strictObject({
|
|
3048
|
+
ref: reference,
|
|
3049
|
+
fingerprint: text4,
|
|
3050
|
+
transcript_id: id2,
|
|
3051
|
+
content_hash: nullable(text4),
|
|
3052
|
+
position: count5,
|
|
3053
|
+
start_ms: count5,
|
|
3054
|
+
end_ms: count5,
|
|
3055
|
+
speaker_participant_id: nullable(id2),
|
|
3056
|
+
speaker_name: nullable(text4),
|
|
3057
|
+
text: text4,
|
|
3058
|
+
revision
|
|
3059
|
+
}))
|
|
3060
|
+
});
|
|
3061
|
+
var event = strictObject({
|
|
3062
|
+
id: pipe(string(), minLength(1)),
|
|
3063
|
+
event_series_id: nullable(text4),
|
|
3064
|
+
title: nullable(text4),
|
|
3065
|
+
description: nullable(text4),
|
|
3066
|
+
location: nullable(text4),
|
|
3067
|
+
starts_at: nullable(isoTime),
|
|
3068
|
+
ends_at: nullable(isoTime),
|
|
3069
|
+
timezone: nullable(text4),
|
|
3070
|
+
/** `auto`: made from a meeting; `owner`: made by hand; `calendar`: from a calendar's entries. */
|
|
3071
|
+
origin: picklist(["auto", "owner", "calendar"]),
|
|
3072
|
+
status: nullable(text4),
|
|
3073
|
+
all_day: boolean(),
|
|
3074
|
+
/** When its calendar deleted it: shown as "deleted in Google", kept as history. */
|
|
3075
|
+
source_deleted_at: nullable(isoTime),
|
|
3076
|
+
deleted_at: nullable(isoTime),
|
|
3077
|
+
created_at: isoTime,
|
|
3078
|
+
updated_at: isoTime,
|
|
3079
|
+
/** The fields whoever sent the invitation wrote, on a calendar CLI's `events list`: an agent reads them as data. */
|
|
3080
|
+
untrusted: optional(array(text4)),
|
|
3081
|
+
/** On a calendar CLI's `events list changed:<date>`: what changed since then, and when the store saw it. */
|
|
3082
|
+
change: optional(picklist(["new", "moved", "cancelled"])),
|
|
3083
|
+
changed_at: optional(nullable(isoTime)),
|
|
3084
|
+
/** The times a moved event had at that date. */
|
|
3085
|
+
was: optional(strictObject({ starts_at: nullable(isoTime), ends_at: nullable(isoTime) })),
|
|
3086
|
+
/**
|
|
3087
|
+
* Whether its time overlaps another event's, in the accounts read: a timed event, not cancelled, not declined, not
|
|
3088
|
+
* free and no working-location block. On a calendar CLI's `events list` when the query names it.
|
|
3089
|
+
*/
|
|
3090
|
+
overlapping: optional(boolean()),
|
|
3091
|
+
/** With `overlapping:true`: the events it overlaps, as `event:<id>`. */
|
|
3092
|
+
overlaps: optional(array(text4))
|
|
3093
|
+
});
|
|
3094
|
+
var eventItem = /* @__PURE__ */ __name((one) => ({
|
|
3095
|
+
id: String(one.id),
|
|
3096
|
+
event_series_id: one.eventSeriesId === null ? null : String(one.eventSeriesId),
|
|
3097
|
+
title: one.title,
|
|
3098
|
+
description: one.description,
|
|
3099
|
+
location: one.location,
|
|
3100
|
+
starts_at: iso3(one.startsAt),
|
|
3101
|
+
ends_at: iso3(one.endsAt),
|
|
3102
|
+
timezone: one.timezone,
|
|
3103
|
+
origin: one.origin,
|
|
3104
|
+
status: one.status ?? null,
|
|
3105
|
+
all_day: one.allDay === true,
|
|
3106
|
+
source_deleted_at: iso3(one.sourceDeletedAt ?? null),
|
|
3107
|
+
deleted_at: iso3(one.deletedAt),
|
|
3108
|
+
created_at: new Date(one.createdAt).toISOString(),
|
|
3109
|
+
updated_at: new Date(one.updatedAt).toISOString()
|
|
3110
|
+
}), "eventItem");
|
|
3111
|
+
|
|
3112
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/recording-transfer.js
|
|
3113
|
+
var strongRecordingValidator = /* @__PURE__ */ __name((value) => typeof value === "string" && value.length <= 1024 && /^"[\x21\x23-\x7e\x80-\xff]*"$/.test(value), "strongRecordingValidator");
|
|
3114
|
+
|
|
3115
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/related-history.js
|
|
3116
|
+
var validateMeetingRelatedHistory = /* @__PURE__ */ __name((original) => {
|
|
3117
|
+
if (!original || typeof original !== "object" || Array.isArray(original))
|
|
3118
|
+
throw new CliError("validation_error", "related history request is required");
|
|
3119
|
+
const input = { ...original };
|
|
3120
|
+
for (const field of Object.keys(input))
|
|
3121
|
+
if (!["accountId", "seriesId", "anchorIds", "after", "before", "limit", "maxReadBytes", "signal"].includes(field))
|
|
3122
|
+
throw new CliError("validation_error", `unknown related history field: ${field}`);
|
|
3123
|
+
const positive = /* @__PURE__ */ __name((value) => Number.isSafeInteger(value) && value > 0, "positive");
|
|
3124
|
+
if (!positive(input.accountId) || !positive(input.seriesId))
|
|
3125
|
+
throw new CliError("validation_error", "accountId and seriesId must be positive safe integers");
|
|
3126
|
+
if (!Array.isArray(input.anchorIds) || input.anchorIds.length > 20 || input.anchorIds.some((id3) => !positive(id3)))
|
|
3127
|
+
throw new CliError("validation_error", "anchorIds must contain at most 20 positive safe integers");
|
|
3128
|
+
for (const key of ["after", "before"])
|
|
3129
|
+
if (!Number.isSafeInteger(input[key]) || Math.abs(input[key]) > 864e13)
|
|
3130
|
+
throw new CliError("validation_error", `${key} must be an absolute timestamp`);
|
|
3131
|
+
if (input.after >= input.before)
|
|
3132
|
+
throw new CliError("validation_error", "after must precede before");
|
|
3133
|
+
const limit = input.limit === void 0 ? 5 : input.limit;
|
|
3134
|
+
const maxReadBytes = input.maxReadBytes === void 0 ? 262144 : input.maxReadBytes;
|
|
3135
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 20)
|
|
3136
|
+
throw new CliError("validation_error", "limit must be an integer from 1 to 20");
|
|
3137
|
+
if (!Number.isSafeInteger(maxReadBytes) || maxReadBytes < 1 || maxReadBytes > 4194304)
|
|
3138
|
+
throw new CliError("validation_error", "maxReadBytes must be an integer from 1 to 4194304");
|
|
3139
|
+
if (input.signal !== void 0 && !(input.signal instanceof AbortSignal))
|
|
3140
|
+
throw new CliError("validation_error", "signal must be an AbortSignal");
|
|
3141
|
+
input.signal?.throwIfAborted();
|
|
3142
|
+
return { ...input, anchorIds: [...new Set(input.anchorIds)], limit, maxReadBytes };
|
|
3143
|
+
}, "validateMeetingRelatedHistory");
|
|
3144
|
+
|
|
3145
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/review.js
|
|
3146
|
+
var REVIEW_LIMIT = { default: 50, most: 200 };
|
|
3147
|
+
|
|
3148
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/save-hints.js
|
|
3149
|
+
var SAVE_HELP = `Worth keeping \u2014 a decision, a promise, a preference? Record it with \`memo facts add\` or
|
|
3150
|
+
\`memo memories add\`, citing the msg: locator or meeting: reference as --evidence.`;
|
|
3151
|
+
|
|
3152
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/series-history.js
|
|
3153
|
+
var validateMeetingSeriesHistory = /* @__PURE__ */ __name((input) => {
|
|
3154
|
+
input.signal?.throwIfAborted();
|
|
3155
|
+
if (!Number.isSafeInteger(input.accountId) || input.accountId <= 0)
|
|
3156
|
+
throw new CliError("validation_error", "accountId must be a positive safe integer");
|
|
3157
|
+
if (typeof input.externalId !== "string" || !input.externalId.trim() || new TextEncoder().encode(input.externalId).length > 4096 || /[\0\r\n]/.test(input.externalId))
|
|
3158
|
+
throw new CliError("validation_error", "externalId must be a bounded nonempty series identifier");
|
|
3159
|
+
for (const name of ["after", "before"])
|
|
3160
|
+
if (!Number.isSafeInteger(input[name]) || Math.abs(input[name]) > 864e13)
|
|
3161
|
+
throw new CliError("validation_error", `${name} must be an absolute timestamp in milliseconds`);
|
|
3162
|
+
if (input.after >= input.before)
|
|
3163
|
+
throw new CliError("validation_error", "after must be earlier than before");
|
|
3164
|
+
const limit = input.limit === void 0 ? 20 : input.limit;
|
|
3165
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100)
|
|
3166
|
+
throw new CliError("validation_error", "limit must be an integer from 1 to 100");
|
|
3167
|
+
const maxReadBytes = input.maxReadBytes === void 0 ? 256 * 1024 : input.maxReadBytes;
|
|
3168
|
+
if (!Number.isSafeInteger(maxReadBytes) || maxReadBytes < 1 || maxReadBytes > 4 * 1024 * 1024)
|
|
3169
|
+
throw new CliError("validation_error", "maxReadBytes must be an integer from 1 to 4194304");
|
|
3170
|
+
return { ...input, limit, maxReadBytes };
|
|
3171
|
+
}, "validateMeetingSeriesHistory");
|
|
3172
|
+
|
|
3173
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/upcoming-validation.js
|
|
3174
|
+
var occurrenceId = /* @__PURE__ */ __name((value) => typeof value === "string" && value.trim().length > 0 && value.length <= 1e3 && !/[\0\r\n]/.test(value), "occurrenceId");
|
|
3175
|
+
|
|
3176
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/series-inventory-validation.js
|
|
3177
|
+
function invalid4(field, response = false) {
|
|
3178
|
+
throw new CliError(response ? "invalid_response" : "validation_error", `invalid meeting inventory ${field}`);
|
|
3179
|
+
}
|
|
3180
|
+
__name(invalid4, "invalid");
|
|
3181
|
+
var object2 = /* @__PURE__ */ __name((value, fields, field, response = false) => {
|
|
3182
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
3183
|
+
invalid4(field, response);
|
|
3184
|
+
for (const key of Object.keys(value))
|
|
3185
|
+
if (!fields.includes(key))
|
|
3186
|
+
invalid4(`${field}.${key}`, response);
|
|
3187
|
+
}, "object");
|
|
3188
|
+
var cursorDetails = /* @__PURE__ */ __name((value) => {
|
|
3189
|
+
if (typeof value !== "string" || value.length > 4096 || !/^[A-Za-z0-9_-]+$/.test(value))
|
|
3190
|
+
invalid4("cursor");
|
|
3191
|
+
try {
|
|
3192
|
+
const decoded = JSON.parse(new TextDecoder("utf8", { fatal: true }).decode(Buffer.from(value, "base64url")));
|
|
3193
|
+
object2(decoded, ["version", "selection", "cursor"], "cursor");
|
|
3194
|
+
if (decoded.version !== 1 || typeof decoded.selection !== "string" || !/^[a-f0-9]{64}$/.test(decoded.selection) || !occurrenceId(decoded.cursor))
|
|
3195
|
+
invalid4("cursor");
|
|
3196
|
+
return decoded;
|
|
3197
|
+
} catch {
|
|
3198
|
+
return invalid4("cursor");
|
|
3199
|
+
}
|
|
3200
|
+
}, "cursorDetails");
|
|
3201
|
+
var validateMeetingSeriesInventoryCursor = /* @__PURE__ */ __name((value) => {
|
|
3202
|
+
cursorDetails(value);
|
|
3203
|
+
}, "validateMeetingSeriesInventoryCursor");
|
|
3204
|
+
|
|
3205
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/meetings/stats.js
|
|
3206
|
+
var MEETING_COUNTS_GROUPINGS = ["day", "week", "series"];
|
|
3207
|
+
var zoneOf = /* @__PURE__ */ __name((timeZone) => {
|
|
3208
|
+
const zone = timeZone ?? "UTC";
|
|
3209
|
+
try {
|
|
3210
|
+
new Intl.DateTimeFormat("en", { timeZone: zone });
|
|
3211
|
+
} catch {
|
|
3212
|
+
throw new CliError("validation_error", "expected an IANA time zone such as Europe/Madrid");
|
|
3213
|
+
}
|
|
3214
|
+
return zone;
|
|
3215
|
+
}, "zoneOf");
|
|
3216
|
+
var DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
|
3217
|
+
var weekStart = /* @__PURE__ */ __name((at, format) => {
|
|
3218
|
+
const parts = Object.fromEntries(format.formatToParts(new Date(at)).map((part) => [part.type, part.value]));
|
|
3219
|
+
const day = Date.UTC(Number(parts.year), Number(parts.month) - 1, Number(parts.day));
|
|
3220
|
+
return new Date(day - DAYS.indexOf(parts.weekday ?? "Mon") * 864e5).toISOString().slice(0, 10);
|
|
3221
|
+
}, "weekStart");
|
|
3222
|
+
var dayKey = /* @__PURE__ */ __name((at, format) => {
|
|
3223
|
+
const parts = Object.fromEntries(format.formatToParts(new Date(at)).map((part) => [part.type, part.value]));
|
|
3224
|
+
return `${parts.year}-${parts.month}-${parts.day}`;
|
|
3225
|
+
}, "dayKey");
|
|
3226
|
+
var zoneFormat = /* @__PURE__ */ __name((zone) => new Intl.DateTimeFormat("en-US", {
|
|
3227
|
+
timeZone: zone,
|
|
3228
|
+
year: "numeric",
|
|
3229
|
+
month: "2-digit",
|
|
3230
|
+
day: "2-digit",
|
|
3231
|
+
weekday: "short"
|
|
3232
|
+
}), "zoneFormat");
|
|
3233
|
+
var NO_SERIES = "no-series";
|
|
3234
|
+
var MOST_COUNT_ROWS = 100;
|
|
3235
|
+
var minutesOf = /* @__PURE__ */ __name((ms) => Math.round(ms / 6e4), "minutesOf");
|
|
3236
|
+
var meanOf = /* @__PURE__ */ __name((ms, timed) => timed === 0 ? null : Math.round(ms / timed / 6e3) / 10, "meanOf");
|
|
3237
|
+
var aggregateMeetingCounts = /* @__PURE__ */ __name((meetings, by, timeZone, limit = MOST_COUNT_ROWS) => {
|
|
3238
|
+
if (!MEETING_COUNTS_GROUPINGS.includes(by))
|
|
3239
|
+
throw new CliError("validation_error", `--by takes ${MEETING_COUNTS_GROUPINGS.join(", ")}`);
|
|
3240
|
+
if (!Number.isSafeInteger(limit) || limit < 1)
|
|
3241
|
+
throw new CliError("validation_error", "--limit is a positive number");
|
|
3242
|
+
const zone = zoneOf(timeZone);
|
|
3243
|
+
const format = zoneFormat(zone);
|
|
3244
|
+
const sum = /* @__PURE__ */ __name(() => ({ meetings: 0, ms: 0, timed: 0, transcripts: 0 }), "sum");
|
|
3245
|
+
const add = /* @__PURE__ */ __name((into, meeting2) => {
|
|
3246
|
+
into.meetings += 1;
|
|
3247
|
+
if (meeting2.durationMs !== null) {
|
|
3248
|
+
into.ms += Math.max(0, meeting2.durationMs);
|
|
3249
|
+
into.timed += 1;
|
|
3250
|
+
}
|
|
3251
|
+
if (meeting2.transcribed)
|
|
3252
|
+
into.transcripts += 1;
|
|
3253
|
+
}, "add");
|
|
3254
|
+
const total = { ...sum(), name: null };
|
|
3255
|
+
const groups = /* @__PURE__ */ new Map();
|
|
3256
|
+
for (const meeting2 of meetings) {
|
|
3257
|
+
add(total, meeting2);
|
|
3258
|
+
const key = by === "series" ? meeting2.seriesKey === null ? NO_SERIES : `series:${meeting2.seriesKey}` : meeting2.startedAt === null ? null : by === "day" ? dayKey(meeting2.startedAt, format) : weekStart(meeting2.startedAt, format);
|
|
3259
|
+
if (key === null)
|
|
3260
|
+
continue;
|
|
3261
|
+
const group = groups.get(key) ?? { ...sum(), name: by === "series" ? meeting2.seriesTitle : null };
|
|
3262
|
+
add(group, meeting2);
|
|
3263
|
+
groups.set(key, group);
|
|
3264
|
+
}
|
|
3265
|
+
const ordered = [...groups.entries()].sort(([a, one], [b, other]) => by === "series" ? other.ms - one.ms || other.meetings - one.meetings || a.localeCompare(b) : b.localeCompare(a));
|
|
3266
|
+
const kept = ordered.slice(0, limit);
|
|
3267
|
+
if (by !== "series")
|
|
3268
|
+
kept.reverse();
|
|
3269
|
+
const counted = /* @__PURE__ */ __name(({ meetings: count6, ms, timed, transcripts }) => ({
|
|
3270
|
+
meetings: count6,
|
|
3271
|
+
minutes: minutesOf(ms),
|
|
3272
|
+
meanMinutes: meanOf(ms, timed),
|
|
3273
|
+
transcripts
|
|
3274
|
+
}), "counted");
|
|
3275
|
+
return {
|
|
3276
|
+
by,
|
|
3277
|
+
timeZone: zone,
|
|
3278
|
+
...counted(total),
|
|
3279
|
+
rows: kept.map(([key, group]) => ({ key, name: group.name, ...counted(group) })),
|
|
3280
|
+
hasMore: ordered.length > limit
|
|
3281
|
+
};
|
|
3282
|
+
}, "aggregateMeetingCounts");
|
|
3283
|
+
var UNKNOWN_SPEAKER = "unknown";
|
|
3284
|
+
var speakerOf = /* @__PURE__ */ __name((row) => row.personId !== null ? { key: `person:${row.personId}`, name: row.personName ?? row.identityName ?? row.speakerName } : row.identityId !== null ? { key: `identity:${row.identityId}`, name: row.identityName ?? row.speakerName } : row.speakerName?.trim() ? { key: `name:${row.speakerName.trim().toLowerCase()}`, name: row.speakerName.trim() } : { key: UNKNOWN_SPEAKER, name: null }, "speakerOf");
|
|
3285
|
+
var aggregateMeetingStats = /* @__PURE__ */ __name((rows, timeZone) => {
|
|
3286
|
+
const zone = zoneOf(timeZone);
|
|
3287
|
+
const format = zoneFormat(zone);
|
|
3288
|
+
const speakers = /* @__PURE__ */ new Map();
|
|
3289
|
+
const weeks = /* @__PURE__ */ new Map();
|
|
3290
|
+
const meetings = /* @__PURE__ */ new Set();
|
|
3291
|
+
let lines = 0;
|
|
3292
|
+
let words2 = 0;
|
|
3293
|
+
let talkMs = 0;
|
|
3294
|
+
for (const row of rows) {
|
|
3295
|
+
const talk = Math.max(0, row.endMs - row.startMs);
|
|
3296
|
+
meetings.add(row.meetingId);
|
|
3297
|
+
lines += 1;
|
|
3298
|
+
words2 += row.words;
|
|
3299
|
+
talkMs += talk;
|
|
3300
|
+
const who = speakerOf(row);
|
|
3301
|
+
const held = speakers.get(who.key) ?? {
|
|
3302
|
+
key: who.key,
|
|
3303
|
+
name: who.name ?? null,
|
|
3304
|
+
personId: row.personId,
|
|
3305
|
+
identityId: row.personId === null ? row.identityId : null,
|
|
3306
|
+
meetings: 0,
|
|
3307
|
+
lines: 0,
|
|
3308
|
+
words: 0,
|
|
3309
|
+
talkMs: 0,
|
|
3310
|
+
share: 0,
|
|
3311
|
+
seen: /* @__PURE__ */ new Set()
|
|
3312
|
+
};
|
|
3313
|
+
held.seen.add(row.meetingId);
|
|
3314
|
+
held.lines += 1;
|
|
3315
|
+
held.words += row.words;
|
|
3316
|
+
held.talkMs += talk;
|
|
3317
|
+
speakers.set(who.key, held);
|
|
3318
|
+
if (row.startedAt !== null) {
|
|
3319
|
+
const week = weeks.get(weekStart(row.startedAt, format)) ?? { meetings: /* @__PURE__ */ new Set(), talkMs: 0 };
|
|
3320
|
+
week.meetings.add(row.meetingId);
|
|
3321
|
+
week.talkMs += talk;
|
|
3322
|
+
weeks.set(weekStart(row.startedAt, format), week);
|
|
3323
|
+
}
|
|
3324
|
+
}
|
|
3325
|
+
return {
|
|
3326
|
+
timeZone: zone,
|
|
3327
|
+
meetings: meetings.size,
|
|
3328
|
+
lines,
|
|
3329
|
+
words: words2,
|
|
3330
|
+
talkMs,
|
|
3331
|
+
speakers: [...speakers.values()].map(({ seen, ...speaker }) => ({
|
|
3332
|
+
...speaker,
|
|
3333
|
+
meetings: seen.size,
|
|
3334
|
+
share: talkMs === 0 ? 0 : Math.round(speaker.talkMs / talkMs * 1e3) / 1e3
|
|
3335
|
+
})).sort((a, b) => b.talkMs - a.talkMs || a.key.localeCompare(b.key)),
|
|
3336
|
+
weeks: [...weeks.entries()].map(([start, week]) => ({ weekStart: start, meetings: week.meetings.size, talkMs: week.talkMs })).sort((a, b) => a.weekStart.localeCompare(b.weekStart))
|
|
3337
|
+
};
|
|
3338
|
+
}, "aggregateMeetingStats");
|
|
3339
|
+
|
|
3340
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/domain/tags.js
|
|
3341
|
+
var TAG_TYPES = ["chat", "contact", "message", "task"];
|
|
3342
|
+
var TAG = /^[a-z0-9-]{1,32}$/;
|
|
3343
|
+
var tagOf = /* @__PURE__ */ __name((value) => {
|
|
3344
|
+
const tag = value.trim().toLowerCase();
|
|
3345
|
+
return TAG.test(tag) ? tag : void 0;
|
|
3346
|
+
}, "tagOf");
|
|
3347
|
+
var normalizeTag = /* @__PURE__ */ __name((value) => {
|
|
3348
|
+
const tag = tagOf(value);
|
|
3349
|
+
if (tag === void 0)
|
|
3350
|
+
throw new CliError("validation_error", `"${singleLine(value)}" is not a tag \u2014 use 1\u201332 letters a\u2013z, digits and hyphens`, { reason: "tag.invalid" });
|
|
3351
|
+
return tag;
|
|
3352
|
+
}, "normalizeTag");
|
|
3353
|
+
|
|
3354
|
+
export {
|
|
3355
|
+
parseDecimal,
|
|
3356
|
+
formatDecimal,
|
|
3357
|
+
currencyOf,
|
|
3358
|
+
scaleOf,
|
|
3359
|
+
minorUnits,
|
|
3360
|
+
moneyOf,
|
|
3361
|
+
moneyLabel,
|
|
3362
|
+
quantityOf,
|
|
3363
|
+
lineUnits,
|
|
3364
|
+
INVOICE_DIRECTIONS,
|
|
3365
|
+
INVOICE_STATUSES,
|
|
3366
|
+
MONEY_DIRECTIONS,
|
|
3367
|
+
FINANCE_REVIEWS,
|
|
3368
|
+
settledStatus,
|
|
3369
|
+
invoiceLine,
|
|
3370
|
+
paymentLine,
|
|
3371
|
+
invoiceTitle,
|
|
3372
|
+
paymentEntryTitle,
|
|
3373
|
+
ORDER_STATUSES,
|
|
3374
|
+
ORDER_PURPOSES,
|
|
3375
|
+
orderLine,
|
|
3376
|
+
orderTitle,
|
|
3377
|
+
QUERY_LIMITS,
|
|
3378
|
+
queryAstSchema,
|
|
3379
|
+
queryError,
|
|
3380
|
+
walkQuery,
|
|
3381
|
+
timezoneOf,
|
|
3382
|
+
dayBoundary,
|
|
3383
|
+
zonedMoment,
|
|
3384
|
+
dateRange,
|
|
3385
|
+
evaluate,
|
|
3386
|
+
FIELD_TYPES,
|
|
3387
|
+
OPERATORS_BY_TYPE,
|
|
3388
|
+
QUERY_BACKENDS,
|
|
3389
|
+
queryFieldsOf,
|
|
3390
|
+
fieldsHelp,
|
|
3391
|
+
queryDescription,
|
|
3392
|
+
parseLucene,
|
|
3393
|
+
implicitTextTerms,
|
|
3394
|
+
validateQuery,
|
|
3395
|
+
fieldsNamed,
|
|
3396
|
+
describeQuery,
|
|
3397
|
+
defineQuery,
|
|
3398
|
+
QUERY_REASONS,
|
|
3399
|
+
formatMeetingReference,
|
|
3400
|
+
parseMeetingReference,
|
|
3401
|
+
canonicalMeetingReference,
|
|
3402
|
+
meeting,
|
|
3403
|
+
MEETING_QUERY,
|
|
3404
|
+
meetingHit,
|
|
3405
|
+
meetingTranscript,
|
|
3406
|
+
meetingSummary,
|
|
3407
|
+
meetingDetails,
|
|
3408
|
+
meetingHitsList,
|
|
3409
|
+
joinKeyOf,
|
|
3410
|
+
joinUrlWithoutQuery,
|
|
3411
|
+
calendarText,
|
|
3412
|
+
entryMetadata,
|
|
3413
|
+
meetingCueFingerprint,
|
|
3414
|
+
EVENT_QUERY,
|
|
3415
|
+
entryInWindow,
|
|
3416
|
+
normalizeMeetingParticipantQuery,
|
|
3417
|
+
validateMeetingParticipantSearch,
|
|
3418
|
+
MeetingError,
|
|
3419
|
+
listed,
|
|
3420
|
+
meetingPeople,
|
|
3421
|
+
meetingsList,
|
|
3422
|
+
meetingsQuery,
|
|
3423
|
+
MEETING_QUERY_GUIDE,
|
|
3424
|
+
meetingDetailsAnswer,
|
|
3425
|
+
meetingTranscriptAnswer,
|
|
3426
|
+
meetingSummaryAnswer,
|
|
3427
|
+
exportMeeting,
|
|
3428
|
+
FACT_TYPES,
|
|
3429
|
+
validatePayment,
|
|
3430
|
+
paymentTitle,
|
|
3431
|
+
meetingTimestamp,
|
|
3432
|
+
findingText,
|
|
3433
|
+
findingHash,
|
|
3434
|
+
findingFields,
|
|
3435
|
+
findingNeeds,
|
|
3436
|
+
validEvidence,
|
|
3437
|
+
findingId,
|
|
3438
|
+
validateFinding,
|
|
3439
|
+
validateBatch,
|
|
3440
|
+
validateFindings,
|
|
3441
|
+
findingFingerprint,
|
|
3442
|
+
MEETING_FINDINGS_KIND,
|
|
3443
|
+
validateMeetingFindings,
|
|
3444
|
+
meetingFindingFingerprint,
|
|
3445
|
+
parseMeetingQuery,
|
|
3446
|
+
transcriptLanguage,
|
|
3447
|
+
importFiles,
|
|
3448
|
+
CHAT_MESSAGES_READ,
|
|
3449
|
+
validateMeetingChange,
|
|
3450
|
+
validateMeetingPassage,
|
|
3451
|
+
validateMeetingPreparationContext,
|
|
3452
|
+
meetingProjectEvidence,
|
|
3453
|
+
meetingProjectEvidenceAnswer,
|
|
3454
|
+
validateMeetingHitSearch,
|
|
3455
|
+
MEETING_PROJECT_EVIDENCE_QUERY,
|
|
3456
|
+
prepareMeetingProjectEvidence,
|
|
3457
|
+
readMeetingProjectEvidence,
|
|
3458
|
+
pull,
|
|
3459
|
+
meetingReview,
|
|
3460
|
+
meetingLink,
|
|
3461
|
+
meetingSpeaker,
|
|
3462
|
+
meetingStats,
|
|
3463
|
+
meetingCounts,
|
|
3464
|
+
meetingParticipants,
|
|
3465
|
+
meetingPassage,
|
|
3466
|
+
event,
|
|
3467
|
+
eventItem,
|
|
3468
|
+
strongRecordingValidator,
|
|
3469
|
+
validateMeetingRelatedHistory,
|
|
3470
|
+
MEETING_RESULT_ENTITIES,
|
|
3471
|
+
REVIEW_LIMIT,
|
|
3472
|
+
SAVE_HELP,
|
|
3473
|
+
validateMeetingSeriesHistory,
|
|
3474
|
+
validateMeetingSeriesInventoryCursor,
|
|
3475
|
+
aggregateMeetingCounts,
|
|
3476
|
+
aggregateMeetingStats,
|
|
3477
|
+
TAG_TYPES,
|
|
3478
|
+
tagOf,
|
|
3479
|
+
normalizeTag
|
|
3480
|
+
};
|